Legal characters in ISO sortable date format - datetime

What are the valid characters for an ISO date? I know of 0 through 9, -, :, T and Z. Are there any more?
I obtain this sortable date format in .NET with .NET's XML serialization and like this:
var stringDate = myDateTime.ToString("s");

It looks like you can also have a W as part of the ISO week date.
You can have a , or . when dealing with decimal fractions that are added to a time element (See the times section here):
To denote "14 hours, 30 and one half minutes", do not include a
seconds figure. Represent it as "14:30,5", "1430,5", "14:30.5", or
"1430.5".
+ is valid when using them with UTC offsets such as 22:30+04 or 1130-0700.
Durations can use a bunch of letters such as P, Y, M, W, D, T, H, M, and S. They are a component of time intervals and define the amount of intervening time in a time interval.
Time intervals are the last one and can use / to split a start and end time.
It looks like the default format when using the s format string on a datetime is yyyy-MM-ddTHH:mm:ss", so the only valid characters in this case would be 0 to 9, -, : and T. The other characters above are part of the ISO 8601 standard which the sortable date/time pattern follows, but might not be applicable unless you deal with a different format string or culture.

Related

Convert string of length 8 to *EUR date for comparing

I want to convert a string of length 8 to a date type for comparing it. The string is formatted as DDMMYYYY (*EUR).
It has no periods for seperating the days from months and months from years. If I input a value like '01012018' to the %date BIF the compiler tells me that the expression is too short for the format *EUR:
D dateEUR s d datfmt(*EUR)
C eval dateEUR = %date('01012018':*EUR)
My previous way to compare to two dates was to take both of them, store them in datastructues, reorder the date with subfields and take the resulting, reordered date from a overlaying subfield.
Has anyone a idea of how to convert the 8A string to a DATE type in RPGLE?
The format you specify will depend on whether or not you store the date separators. If your date is in a 10-byte character field as DD-MM-YYYY (with the dashes), this is again EUR format:
%date(alpha_date : *eur)
If you don'tt need standard separators with your date (DDMMYYYY in an 8-byte character field) simply append the number zero (0) to the end of the format name:
%date(alpha_date : *eur0)

Convert UTC ISO string date to Unix timestamp

I have this UTC date in a Google spreadsheet: 2018-10-18T08:55:13Z and would like to convert it to Unix timestamp (1539852913). I tried this formula, but it's unable to recognize the timevalue:
=DATEVALUE(MID(A1;1;10)) + TIMEVALUE(MID(A1;12;8))
If I can get a valid date and time, I can use this formula to convert to Unix timestamp:
=(A1-$C$1)*86400
Does anyone have a solution for this?
Simpler:
=86400*(left(substitute(A1,"T"," "),19))-2209161600
Replaces T with space and cuts off Z, leaving what's left recognisable as date and time in arithmetical calculations. Convert day and time index into seconds and adjust for the offset.
Assuming your date has proceeding zeros for single digit days and month, pull each date string part and drop it into the DATE formula as follows:
Year
=LEFT(A1,4)
Month
=MID(A1,6,2)
Day
=MID(A1,9,2)
Use the date formula
=DATE(year,month,day)
=DATE(LEFT(A1,4),MID(A1,6,2),MID(A1,9,2))
A similar process can be used for TIME
Hour
=MID(A1,12,2)
Minutes
=MID(A1,15,2)
Seconds
=MID(A1,18,2)
Time
=TIME(Hour,Minutes,Seconds)
=TIME(MID(A1,12,2),MID(A1,15,2),MID(A1,18,2))
1) There are other methods
2) The formulas will need to be adapted if you do not have leading 0 for each unit. In that case you would need to use FIND to identify the position of key characters and measure the distance between them to determine if there was a single digit unit or double digit unit.
Since the date is the integer part (left of the decimal) represents the number of days since 1900/01/01 (with that date being 1) and decimal portion represents time in terms of fraction of a day, to get a full date and time, you would add the date formula to the time formula as follows:
=DATE(LEFT(A1,4),MID(A1,6,2),MID(A1,9,2))+TIME(MID(A1,12,2),MID(A1,15,2),MID(A1,18,2))

R: date/time "YYYY-MM-DDThh:mm:ss.sTZD" import

How can I import the folowing date/time format example in R ? I'm willing to keep all information within this format.
2016-09-12T09:47:00.000+0200
where:
YYYY = four-digit year
MM = two-digit month (01=January, etc.)
DD = two-digit day of month (01 through 31)
hh = two digits of hour (00 through 23) (am/pm NOT allowed)
mm = two digits of minute (00 through 59)
ss = two digits of second (00 through 59)
s = one or more digits representing a decimal fraction of a second
TZD = time zone designator (Z or +hh:mm or -hh:mm)
I've tried strptime without success since I cannot find how to match s and TZD, example:
> strptime("2016-09-12T09:47:00.000+0200", format = '%Y-%m-%dT%H:%M:%S.000%z')
[1] "2016-09-12 09:47:00
To match the decimal fraction of a second (from the docs ?strptime in Examples) use:
format = '%Y-%m-%dT%H:%M:%OS%z'
Then, to see the 3-digits:
op <- options(digits.secs = 3)
strptime("2016-09-12T09:47:00.123+0200", format = '%Y-%m-%dT%H:%M:%OS%z')
##[1] "2016-09-12 03:47:00.123"
To go back to not seeing the 3-digits:
options(op)
I believe this does parse the offset from UTC (i.e., the +0200). I'm on the east coast of the United States, and it is EDT (-0400). Therefore, I'm 6 hours behind (+0200) so that 09:47:00.123+0200 becomes 03:47:00.123 EDT.
You could use the (pretty new) anytime package which does this without formats:
R> anytime("2016-09-12T09:47:00.000+0200")
[1] "2016-09-12 09:47:00 CDT"
R>
I may try to extend it to also recognize the trailing TZ offset as the underlying Boost date_time code supports it. However, I have so far followed R and taken to interpret the time as local time for which it also (automatically) finds the local timezone.
anytime also supports fractional seconds automatically (but you need to ensure you display them):
R> anytime("2016-09-12T09:47:00.123456+0200")
[1] "2016-09-12 09:47:00.123456 CDT"
R>
I tend to work with microsecond data so I tend to have six digits on all the anyway as shown here.

convert string to time in r

I have an array of time strings, for example 115521.45 which corresponds to 11:55:21.45 in terms of an actual clock.
I have another array of time strings in the standard format (HH:MM:SS.0) and I need to compare the two.
I can't find any way to convert the original time format into something useable.
I've tried using strptime but all it does is add a date (the wrong date) and get rid of time decimal places. I don't care about the date and I need the decimal places:
for example
t <- strptime(105748.35, '%H%M%OS') = ... 10:57:48
using %OSn (n = 1,2 etc) gives NA.
Alternatively, is there a way to convert a time such as 10:57:48 to 105748?
Set the options to allow digits in seconds, and then add the date you wish before converting (so that the start date is meaningful).
options(digits.secs=3)
strptime(paste0('2013-01-01 ',105748.35), '%Y-%M-%d %H%M%OS')

Converting time format to numeric with R

In most cases, we convert numeric time to POSIXct format using R. However, if we want to compare two time points, then we would prefer the numeric time format. For example, I have a date format like "2001-03-13 10:31:00",
begin <- "2001-03-13 10:31:00"
Using R, I want to covert this into a numeric (e.g., the Julian time), perhaps something like the passing seconds between 1970-01-01 00:00:00 and 2001-03-13 10:31:00.
Do you have any suggestions?
The Julian calendar began in 45 BC (709 AUC) as a reform of the Roman calendar by Julius Caesar. It was chosen after consultation with the astronomer Sosigenes of Alexandria and was probably designed to approximate the tropical year (known at least since Hipparchus). see http://en.wikipedia.org/wiki/Julian_calendar
If you just want to remove ":" , " ", and "-" from a character vector then this will suffice:
end <- gsub("[: -]", "" , begin, perl=TRUE)
#> end
#[1] "20010313103100"
You should read the section about 1/4 of the way down in ?regex about character classes. Since the "-" is special in that context as a range operator, it needs to be placed first or last.
After your edit then the answer is clearly what #joran wrote, except that you would need first to convert to a DateTime class:
as.numeric(as.POSIXct(begin))
#[1] 984497460
The other point to make is that comparison operators do work for Date and DateTime classed variables, so the conversion may not be necessary at all. This compares 'begin' to a time one second later and correctly reports that begin is earlier:
as.POSIXct(begin) < as.POSIXct(begin) +1
#[1] TRUE
Based on the revised question this should do what you want:
begin <- "2001-03-13 10:31:00"
as.numeric(as.POSIXct(begin))
The result is a unix timestamp, the number of seconds since epoch, assuming the timestamp is in the local time zone.
Maybe this could also work:
library(lubridate)
...
df <- '24:00:00'
as.numeric(hms(df))
hms() will convert your data from one time format into another, this will let you convert it into seconds. See full documentation.
I tried this because i had trouble with data which was in that format but over 24 hours.
The example from ?as.POSIX help gives
as.POSIXct(strptime(begin, "%Y-%m-%d %H:%M:%S"))
so for you it would be
as.numeric(as.POSIXct(strptime(begin, "%Y-%m-%d %H:%M:%S")))

Resources