Trying to build Expression for Table field to sort text dates, some with missing elements - date

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

Related

Get the whole range of date in SAS

I know the date in SAS looks like 01Jan2017. What I want is 1 January 2017. Is there function to make it?
Thank,
Andrea
Your question is pretty vague - it's hard to tell if you just want to display it differently or store it differently.
Display it differently: Just change the format to keep the date as a number in the background (number of days since 01JAN1960) but display it how you would like.
data ds1;
date = '01JAN2017'd;
format date WORDDATX20.;
run;
Store it differently: You can use the put function to create a separate character variable containing the formatted version of your date.
data ds2;
date1 = '01JAN2017'd;
date2 = put(date1, WORDDATX20.);
run;
Answers provided by Bhavika and pm2r should also help you understand what's going on here.
your code would look like this:
data _null_;
length date1 8. string $40;
date1=today();
string = cats( date1 );
put string=;
string = cats( put(date1,date10.) );
put string=;
string = cats( put(date1,WORDDATX20.) );
put string=;
run;
and the output would be:
string=20838
string=19JAN2017
string=19 January 2017

displaying dates of values - time series data

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.

VB Scripting - comparing time values, one coming from a text file?

I'm attempting to pull some information out of text file that is updated after I query a piece of equipment. The text file contains lines such as shown here (abbreviated):
05-Nov-13 11:11:54.3496 ( -1 7020 10244) scpeng.exe:Automation Server...
05-Nov-13 14:10:54.3496 ( -1 7020 10244) scpeng.exe:Automation Server...
05-Nov-13 14:10:54.3496 ( -1 7020 10244) scpeng.exe:Automation Server...
05-Nov-13 14:10:56.3496 ( -1 7020 10244) scpeng.exe:CServer.cpp,....
The text file can contain up to several weeks of information. I have a subroutine that will run a few seconds after I query the equipment which should allow for the reply and the applicable line to be present in the text file. In the routine, I am trying to scroll through the lines examining the date to arrive at the date of the subroutine call followed by the time (or a time ~10 seconds prior the the current time) to arrive at the lines pertinent to where the information could be found.
do
msg = msgstream.ReadLine
logdate = mide(msg,1,9)
logday = Cdate(logdate)
loop while logday < date
do
msg = msgstream.Readline
logtime = mid(msg,12,8)
'logtime = CDate(logtime) This mod is not working
loop while logtime < time
The date loop appears to work however the time is giving me problems. It does not error out but I can't get it to run beyond one line of text. Can anyone suggest a fix or better option? I have read that the built-in Date function can include the time but I do not believe this version I'm using does. Also, the text file contains times in a 24 hour format where I believe the time function returns values in a 12 hr format ie "12:43:27 PM ST".
You're making this way too complicated. Simply parse the whole date string into a datetime value:
refdate = Now
Do
msg = msgstream.ReadLine
logdate = CDate(Mid(msg, 1, 19))
Loop While logdate < refdate
You can extract date and time portions from the value later, e.g. like this:
WScript.Echo DateValue(logdate)
WScript.Echo TimeValue(logdate)
Also, Time returns the current (unformatted) system time. Whether it's displayed in 12 hour or 24 hour format depends on your system's region settings. However, you can always get the hour (0-23) by using the Hour function.
Parse each line with a regex to get the correct date and time part. I prefer a regexp above string manipulation functions because you can separate format and code.
Reassemble the date from the two parts and see if the date is smaller than yesterday at this time.
Option Explicit
dim strTest, re, matches, myDatePart, myTimePart, logDate
' teststring
strTest = "08-Nov-13 14:10:56.3496 ( -1 7020 10244) scpeng.exe:CServer.cpp,...."
Set re = new regexp
' This pattern extracts two part, the date as (dd-www-dd) and the time as (hh:mm:ss)
re.pattern = "(\d{2}-\w{3}-\d{2}) +(\d{2}:\d{2}:\d{2})"
Set matches = re.Execute(strTest)
' Get the first and second submatch to define the date and time
myDatePart = matches(0).submatches(0)
myTimePart = matches(0).submatches(1)
' datevalue and timevalue automatically tranforms to Date type
logDate = datevalue(myDatePart) + timevalue(myTimePart)
' See if the date is smaller than yesterday exactly this time
msgbox (logDate < (DateAdd("d", -1, now))) ' Returns True, because 08 Nov is earlier than yesterday.

MatLab cells date format conversion

I have a lot of dates in MatLab (over 2 millions). Al these dates are in a cell array in 'yyyymmdd' format, and I want to convert them to 'yyyy-mm-dd' format and put this result in a cell array (not in a char matrix).
I know that I can use
temp = datestr(datenum(datesArray,'yyyymmdd'),'yyyy-mm-dd'),
and then use
mat2cell(temp, ones(1,n),10),
where n is the number of rows of datesArray (in this case approximately 2 millions) in order to get my result, but this approach is very slow.
So, I want to know a different way to do that.
Regards.
You could avoid for loops by using cellfun, let's say your date cell array is
dates = {'20120101', '20120102', '20120103'}
You can then convert them to your format as
cellfun(#(x)[x(1:4),'-',x(5:6),'-',x(7:8)], dates, 'Uniform', false)
Hope that helps.
If your date format is always "yyyymmdd" and it's in a linear cell array called datesArray, you could maybe do it by accessing the strings in datesArray and transforming them by inserting hyphens and concatenating the string.
for i=1:length(datesArray)
newDatesArray{i} = [datesArray{i}(1:4), '-', datesArray{i}(5:6), '-', datesArray{i}(7:8)];
end
Transform your dates into serial one and keep them! However, here's a solution:
% Create dummy dates (takes 10 seconds on my pc)
tic;d = cellstr(datestr(now-2e5+1:now,'yyyymmdd'));toc
% Convert to char, then concatenate with '-' and back to `cellstr()` (1 sec):
c = char(d);
dash = repmat('-',2e5,1);
c = cellstr([c(:,1:4) dash c(:,5:6) dash c(:,7:8)]);
So here my solution, which i think is quite nice!
dates = {'20120101', '20120102', '20120103'}
And you can convert using this :
cellfun(#(x)regexprep(num2str(x), '(?<=\d{4})\d{2}', '-$0'),dates,'Uniform',false)
The answer is similar to radarhead, but it uses the regexprep function instead.

Excel VBA - the date format changes automatically

I'm trying to enter the Date value by adding a month to the date in Sheets("Sheet1").Cells(17, 3).Value which is 01/10/2011 but format as Oct-11. Then return in Sheets("Sheet1").Cells(17, 4).Value = LDate, to show Nov-11
sDate = Sheets("Sheet1").Cells(17, 3).Value --> this shows 01/10/2011 when I hove over sDate
LDate = DateAdd("m", 1, sDate) --> this shows 01/11/2011 when I hove over LDate
I then want to enter that value 01/11/2011 in to the following cell
Sheets("Sheet1").Cells(17, 4).Value = LDate
Selection.NumberFormat = "mmm-yy"
But in the cell it shows 11/01/2011 (Jan-11), why is it doing this and how can I fix this issue?
Minor issue
Selection.NumberFormat = "mmm-yy"
You have not selected anything so this format is placed wherever you left the cursor.
Major issue
You have hit the Excel bug that it will interpret dates as being in American (middle endian) format if it can when transferring data to a worksheet. "1/11/2011" would be "11 Jan 11" to an American so it is to Excel. "20/11/2011" is not a valid American date so to Excel it is "20 Nov 11".
I can duplicate your problem by declaring sDate and LDate as strings. DateAdd works correctly with strings so LDate is correct but when placed in a cell it is misinterpreted.
I can fix your problem by declaring sDate and LDate as dates:
Dim sdate As Date
Dim Ldate As Date
Selection.NumberFormat = "mmm-yy"
Above line is changing the number format. Actually When am running through your steps, I have come across the same issue.
But Number format is doing all this auto change.
Example:
While am running the macro, assume that selected cell is (17,3).
Before running macro: cell value is 01/11/2012
After running macro: cell value will be changed/formatted as "Jan-12". (Since number format is applied as "mmm-yy", so it consider as 01/11/2012 is consider as Jan-12)
Second time, if you select the cell (17,4)
Before running macro: cell value is 2/11/2012
After running macro: cell value will be changed / formatted as "Feb-12"
Instead of trying
Cells(row2,col2) = Cells(row1,col1)
Try this
Cells(row1,col1).Copy
Cells(row2,col2).PasteSpecial Paste:=xlPasteValuesAndNumberFormats