I am trying to maintain a table using some panel data. I have all the data outputting fine, but I am having difficulty getting the correct dates to display. The method I am using is the following:
gen ymdny = date(date,"MDY"); /*<- date var from panel dataset that i import*/
sort name ymdny;
summ ymdny;
local lastdate : disp %tdM-D r(max);
local lastdate2 : disp %tdM-D (r(max)-1);
local lastw : disp %tdM-D (r(max)-7);
This would work fine if the data were daily, but the dataset I have is actually business daily (ie. missing for the weekends and bank national holidays). It seems silly but I have not been able to figure out a workaround that does the job. Ideally - there is a function that i can use to print the corresponding date to a particular value.
For example:
gen resbal_1d = round(l1.resbal,0.1);
gen dateOf = dateOf(resbal_1d); /* <- pseudocode example of what I would like */
I'm not sure what you're asking for but my guess is that you want to see a human readable form date as the output, given a numerical input. (This is your last sentence.) So simply try something like:
display %td 10
The format is important as the following shows (see help format):
display %tq 10
Same numerical input, different format, different output.
Two other examples from the manual:
* string to integer
display date("5-12-1998", "MDY")
* string to date format
display %td date("5-12-1998", "MDY")
As for your example code, I don't get what you're aiming for. In effect, you can summarize the date variable because in Stata, dates are just integers. It's legal but couldn't say if it's good form. Below a simple example.
clear all
set more off
set obs 10
gen date = _n // create the data
format date %td // give date format
list
summarize date
local onedate = r(max)
display %td `onedate'
Some references:
[U] 24 Working with dates and time
help datetime
help datetime business calendars
http://www.stata.com/support/faqs/data-management/creating-date-variables/
http://www.ats.ucla.edu/stat/stata/modules/dates.htm
(Maybe you can explain with more detail and context what it is you want.)
Edit
Your comment
I do not see how this helps with the date output. For example,
displaying r(max) - 1 on a monday will still display the sunday date.
does not explain, at all, the problems you're having with Stata's business calendars.
I'm adding what is basically an example taken from the help file I already referenced. I do this with the hope of convincing you that (re)-reading the help files is worthwhile.
*clear all
set more off
* import string dates
infile str10 sdate float x using http://www.stata-press.com/data/r13/bcal_simple
list
*----- Regular dates -----
* create elapsed dates - Stata's way of managing dates
generate rdate = date(sdate, "MD20Y")
format rdate %td
drop sdate x
list
* compute previous and next dates
generate tomorrow1 = rdate + 1
format tomorrow1 %td
generate yesterday1 = rdate - 1
format yesterday1 %td
list
*----- Business dates -----
* convert regular date to business dates
generate bdate = bofd("simple", rdate)
format bdate %tbsimple
* compute previous and next dates
generate tomorrow2 = bdate + 1
format tomorrow2 %tbsimple
generate yesterday2 = bdate - 1
format yesterday2 %tbsimple
order yesterday1 rdate tomorrow1 yesterday2 bdate tomorrow2
list
/*
The stbcal-file for simple, the calendar shown below,
November 2011
Su Mo Tu We Th Fr Sa
---------------------------
1 2 3 4 X
X 7 8 9 10 11 X
X 14 15 16 17 18 X
X 21 22 23 X X X
X 28 29 30
---------------------------
*/
Notice that if you add or substract 1 from a regular date, then business days are not taken into account. If you do the same with a business calendar date, you get what you want. Business calendars are defined by .stbcal files; the example uses a built-in calendar called simple. You maybe need to make your own .stbcal file but it is not difficult. Again, the details are in the help files.
Related
I was wondering if someone could help me.
I'm very new at ASP I want to format the current date and time as follows:
yyyy-mm-dd hh:mm:ss
But all i can do is the following
Response.Write Date
Can someone help me out please.
Date formatting options are limited in Classic ASP by default, there is a function FormatDateTime() which can format your date is various ways based on the servers regional settings.
For more control over date formatting though there are built in date time functions
Year(date) - Returns a whole number representing the year. Passing Date() will give back the current year.
Month(date) - Returns a whole number between 1 and 12, inclusive, representing the month of the year. Passing Date() will return the current month of the year.
MonthName(month[, abbv]) - Returns a string indicating the specified month. Passing in Month(Date()) as the month will give back the current Month string. As suggested by #Martha
Day(date) - Returns a whole number between 1 and 31, inclusive, representing the day of the month. Passing Date() will return the current day of the month.
Hour(time) - Returns a whole number between 0 and 23, inclusive, representing the hour of the day. Passing Time() will return the current hour.
Minute(time) - Returns a whole number between 0 and 59, inclusive, representing the minute of the hour. Passing Time() will return the current minute.
Second(time) - Returns a whole number between 0 and 59, inclusive, representing the second of the minute. Passing Time() will return the current second.
IMPORTANT:
When formatting date / time values, always store the date / time value first. Also, any needed calculations (DateAdd() etc.) should be applied before attempting to format or you will get unexpected results.
The functions Month(), Day(), Hour(), Minute() and Second() all return whole numbers. Luckily there is an easy workaround that lets you pad these values quickly Right("00" & value, 2) what it does is append 00 to the front of the value then from the right take the first two characters. This ensures that all single digit values return prefixed with a 0.
Dim dd, mm, yy, hh, nn, ss
Dim datevalue, timevalue, dtsnow, dtsvalue
'Store DateTimeStamp once.
dtsnow = Now()
'Individual date components
dd = Right("00" & Day(dtsnow), 2)
mm = Right("00" & Month(dtsnow), 2)
yy = Year(dtsnow)
hh = Right("00" & Hour(dtsnow), 2)
nn = Right("00" & Minute(dtsnow), 2)
ss = Right("00" & Second(dtsnow), 2)
'Build the date string in the format yyyy-mm-dd
datevalue = yy & "-" & mm & "-" & dd
'Build the time string in the format hh:mm:ss
timevalue = hh & ":" & nn & ":" & ss
'Concatenate both together to build the timestamp yyyy-mm-dd hh:mm:ss
dtsvalue = datevalue & " " & timevalue
Call Response.Write(dtsvalue)
Note: You can build the date string in one call but decided to break it down into the three variables to make it easier to read.
How Can I Format Date
Example of Parsing a Date String (Answers provide approaches to taking a date string format and parsing it to a valid Date variable).
Format the date of the previous day format yyyymmdd with VBScript (Example of why storing date / time before performing formatting is important)
VBScript ISO8601 (Example of functions to construct an ISO 8601 compliant date string)
I have a vector of dates in either dmY formats and Ymd format.
These are all dates in the last century.
From each, I need to extract just the year (Y).
I use the following code
library(lubridate)
sampleDates <- c(20100517,17052010)
result <- year(parse_date_time(x, guess_formats(as.character(x), c("Ymd","dmY"))))
result
517 2010
However, I expect something like
result
2010 2010
Here is a base R solution to your problem that takes a particular difficulty into account with your date format. Let's say you have the date 20112020, i.e. November 20th in the year 2020. For your function, it is not easy to distinguish which part of the string is the year - is it 2011 or 2020? The following code takes this difficulty into account, though let me mention that there surely must be simpler solutions.
Code
NonID <- grepl("^2", sampleDates) & (substr(sampleDates, 5, 5) == "2")
ID <- !NonID
dates_normal <- sampleDates[!NonID]
dates_special <- sampleDates[NonID]
normal_years <- as.numeric(c(substr(dates_normal, nchar(dates_normal) - 3, nchar(dates_normal)), substr(dates_normal, 1, 4)))
normal_years <- normal_years[normal_years > 1999]
special_years <- as.numeric(substr(dates_special, nchar(dates_special) - 3, nchar(dates_special)))
all_years <- c(normal_years, special_years)
all_years
> all_years
[1] 2010 2010
Explanation
First, we divide the date vector into those dates which exhibit the indistinguishability (dates_normal) and those which do not (dates_special). Then, for the normal dates, we use the substr() function to extract the first four and last four digits of the string and keep only those values which exceed 2000. For the special dates, we only keep the last four digits because the year can't be possibly included in the first four digits for this date format.
I have column with cell format date or time (DD.MM.YYYY HH:MM:SS) and values like
03.12.2013 14:01:49
04.12.2013 10:19:27
04.12.2013 12:44:56
04.12.2013 14:20:12
04.12.2013 18:30:21
I need those values converted to unix epoch (seconds since 1970). Somehow it feels like the values are not recognized as dates, but rather as strings. I tried different formats, had little luck with dates without time.
Operations performed on date data should be automatic provided that the cells are formatted as as a user defined DD.MM.YYYY HH:MM:SS in the 'Format' > 'Cells' > 'Numbers' tab.
If you're using the standard settings, LibreOffice Calc uses 12/30/1899 as it's default date. So the first step is getting the number of days between 12/30/1899 and 1/1/1970:
=(DATE(1970,1,1) - DATE(1899,12,30)) = 25569
Number of seconds in a day:
=(60 * 60 * 24) = 86400
If, for example, in cell A2 you have the date 03.12.2013 14:01:49. I subtract the difference between Calc's default date and the Unix Epoch we just calculated, and multiply it by the number of seconds in a day:
=(A2 - 25569) * 86400
The result is a value of 1363096909 which is the Epoch time in seconds. If you need it in milliseconds, multiply the equation by 1000.
If it's something you use a lot, you can create a custom function that does this. Go to Tools > Macros > Edit Macros, and type out the following into whichever module comes up:
REM ***** BASIC *****
Function EPOCH(date_cell)
EPOCH = (date_cell - 25569)*86400
End Function
Close the macro IDE, and now you can use your EPOCH() like any other function!
This formula worked for me, where the others above did not:
= DATE( 1970, 1, 1 ) + ( A1 / 86400 )
Hi I am a newbie and have a problem I have been trying to solve for weeks. I have a table imported from excel with dates in text format (because dates go back to 1700s) Most are in the format "mmmyyyy", so it is relatively easy to add "1" to the date, convert to date format, and sort in correct date order. The problem I have is that some of the dates in the table are simply "yyyy", and some are empty. I cannot find an expression that works to convert these last two to eg 1 Jan yyyy and 1 Jan 1000 within the same expression. Is this possible, or would I need to do this in two queries? Sorry if this question is very basic - I cannot find an answer anywhere.
TIA
You can do something like:
Public Function ConvertDate(Byval Expression As Variant) As Date
Dim Result As Date
If IsNull(Expression) Then
Result = DateSerial(1000, 1, 1)
ElseIf Len(Expression) = 4 Then
Result = DateSerial(Expression, 1, 1)
Else
Result = DateValue(Right(Expression, 4) & "/" & Left(Expression, 3) & "/1")
End If
ConvertDate = Result
End Function
I have a dataset for which I have extracted the date at which an event occurred. The date is in the format of MMDDYY although MatLab does not show leading zeros so often it's MDDYY.
Is there a method to find the mean or median (I could use either) date? median works fine when there is an odd number of days but for even numbers I believe it is averaging the two middle ones which doesn't produce sensible values. I've been trying to convert the dates to a MatLab format with regexp and put it back together but I haven't gotten it to work. Thanks
dates=[32381 41081 40581 32381 32981 41081 40981 40581];
You can use datenum to convert dates to a serial date number (1 at 01/01/0000, 2 at 02/01/0000, 367 at 01/01/0001, etc.):
strDate='27112011';
numDate = datenum(strDate,'ddmmyyyy')
Any arithmetic operation can then be performed on these date numbers, like taking a mean or median:
mean(numDates)
median(numDates)
The only problem here, is that you don't have your dates in a string type, but as numbers. Luckily datenum also accepts numeric input, but you'll have to give the day, month and year separated in a vector:
numDate = datenum([year month day])
or as rows in a matrix if you have multiple timestamps.
So for your specified example data:
dates=[32381 41081 40581 32381 32981 41081 40981 40581];
years = mod(dates,100);
dates = (dates-years)./100;
days = mod(dates,100);
months = (dates-days)./100;
years = years + 1900; % set the years to the 20th century
numDates = datenum([years(:) months(:) days(:)]);
fprintf('The mean date is %s\n', datestr(mean(numDates)));
fprintf('The median date is %s\n', datestr(median(numDates)));
In this example I converted the resulting mean and median back to a readable date format using datestr, which takes the serial date number as input.
Try this:
dates=[32381 41081 40581 32381 32981 41081 40981 40581];
d=zeros(1,length(dates));
for i=1:length(dates)
d(i)=datenum(num2str(dates(i)),'ddmmyy');
end
m=mean(d);
m_str=datestr(m,'dd.mm.yy')
I hope this info to be useful, regards
Store the dates as YYMMDD, rather than as MMDDYY. This has the useful side effect that the numeric order of the dates is also the chronological order.
Here is the pseudo-code for a function that you could write.
foreach date:
year = date % 100
date = (date - year) / 100
day = date % 100
date = (date - day) / 100
month = date
newdate = year * 100 * 100 + month * 100 + day
end for
Once you have the dates in YYMMDD format, then find the median (numerically), and this is also the median chronologically.
You see above how to present dates as numbers.
I will add no your issue of finding median of the list. The default matlab median function will average the two middle values when there are an even number of values.
But you can do it yourself! Try this:
dates; % is your array of dates in numeric form
sdates = sort(dates);
mediandate = sdates(round((length(sdates)+1)/2));