I'm working on a program (we'll call this the PostProcessor) that applies some post-processing to the output of another, closed-source program (we'll call this the Original program. Part of the post-processing involves re-calculating a DateTime value and outputting it in the same format as the original.
For example, the Original may output:
03 : 15 : 30 [h:min:s]
The PostProcessor calculates that the actual time should be 4 hours, 20 minutes and 10 seconds and should output:
04 : 20 : 10 [h:min:s]
The "nice" thing is, despite being mostly a black-box, Original program has some configuration settings. Buried deep within these settings is a string value TimeOutputFormat, which PostProcessor can read.
In the above examples, the TimeOutputFormat string was:
%#H : %M : %S [h:min:s]
Another valid format string I've encountered is:
%q2 min
Which outputs the total minutes to 2 decimal places.
From fiddling around, I've also found the %c format string, which outputs in the form:
1/1/1970 03:15:30 AM
which confirms that the Original program is storing these DateTime values in some form of Unix time object.
What I would like to find out is what formatting system is being used, so I can implement it in my PostProcessor. I'm hoping it's a somewhat standard format since I don't have any documentation. The black-box Original program uses a mixture of Visual C++, .NET, and Python modules (and possibly other technologies I'm not aware of).
Here's a catalog of what I've found so far.
# before the letter (i.e. %#d) pads the value with leading 0's
# removes padding from a value %d -> 01 but %#d -> 1
a digit after the letter (i.e. `%d3') displays decimal digits (if the value has them)
Known formatting strings (from trial/error)
%H - Hour component (not total hours, just the hour component)
%M - Minute component
%S - Second component
%a - Day of week (three letter abbrev.)
%b - Month (three letter abbrev.)
%c - Full date (m/d/yyyy HH:MM AM/PM)
%d - Not sure (outputs "01") (guessing day?)
%e-i Not defined
%j - Not sure (outputs "001") (guessing day out of 365?)
%k-l Not defined
%m - Not sure (outputs "01") (guessing month?)
%q - Total minutes
%p - AM/PM
If anyone can identify this formatting system, I'd greatly appreciate it. I'm going to continue to catalog it for my own use, but it would be nice to have some original documentation if it happens to be a publicly available (and hopefully well-documented) system.
Related
I am trying to format a date string using the Apache Nifi expression language and the Replace Text processor(regex). Given a date string
date_str : "2018-12-05T11:44:39.717+01:00",
I wish to convert this to:
correct_mod_date_str: "2018-12-05 10:44:39.717",
(notice how the date is converted to UTC, and character 'T' replaced by a space.)
To do this, I am currently using:
toDate("yyyy-MM-dd'T'HH:mm:ss.SSSSSSXXX"):format("yyyy-MM-dd HH:mm:ss.SSS", '+00:00')
and this works perfectly.
However, when the date string has 6 digits in ms, rather than 3, things break:
another_date_str: "2018-12-05T11:44:39.717456+01:00"
is converted to:
incorrect_mod_date_str: "2018-12-05 10:56:36.456"
It seems the first 3 digits in the ms precision interferes with the conversion.
Appreciate inputs to resolve this - what am I missing?
Regards
seems that's a limitation in java.
according to java documentation there is no support of more then 3 milliseconds digits.
https://docs.oracle.com/javase/8/docs/api/java/text/SimpleDateFormat.html
the simplest way is to remove extra digits like this:
attr:replaceAll('(\.\d{3})\d*','$1'):toDate("yyyy-MM-dd'T'HH:mm:ss.SSSXXX"):format("yyyy-MM-dd HH:mm:ss.SSS", '+00:00')
I ran into a similar issue with date time encoded in ISO 8601. The problem is, that the digits after the second are defined as fragment of a second, not milliseconds.
See answer to related topic
I am doing some "software archaeology" on python-dateutil to fully document (and tighten up) the formats accepted by dateutil.tz.tzstr, and I have come across a strange timezone format that is obviously intended to be explicitly supported (link goes to the code):
# GMT0BST,3,0,30,3600,10,0,26,7200[,3600]
Just reading the code, I've figured out how it works. It starts out like a TZ environment variable:
GMT: Standard time abbreviation
0: Standard offset (in hours)
BST: DST abbreviation
Then the rest is a comma-delimited list, broken into two parts:
3,0,30,3600: DST->STD transition time specifier - month, week of month, day of week, seconds after midnight that the transition happens (note that when "week of month" is 0, the number following is actually the day of the month)
10,0,26,7200: STD->DST transition time specifier - same as above
[,3600]: If specified, this says how big the offset is during DST (default is 1 hour)
The GNU TZ variable equivalent to this string is GMT0BST,J89/1,J299/2:
>>> from dateutil import tz
>>> tz1 = tz.tzstr('GMT0BST,3,0,30,3600,10,0,26,7200')
>>> tz2 = tz.tzstr('GMT0BST,J89/1,J299/2')
>>> tz1 == tz2
True
Is this a standard timezone format somewhere, or just something that one of the earlier maintainers of dateutil added? It seems somewhat strange to add a custom time zone format that expresses exactly the same thing a GNU TZ variable does, but I only ever see "IANA database" and "POSIX TZ variable" as formats when searching for time zone rules.
No, that's not a standard format of any kind (AFAIK). Must be something internal to dateutil.
Note that this appears to be for Europe/London, and the correct POSIX string (for current years) would be GMT0BST,M3.3.0/1,M10.5.0
Does the below 2 syntaxes are same,
moment(1456261200367, 'H:mm:ss.SSS').utc().valueOf() //1456343786120
moment(1456261200367 +0000, 'H:mm:ss.SSS Z').valueOf() //1456325786120
but as you could see if both of them coverts the given value to UTC mode then why there is a difference in the output?
Also I would like to know how a.valueOf() and b.valueOf() are same, when a.format() and b.format() are different, because moment() (moment parses and displays in local time) is different from moment.utc() (displays a moment in UTC mode)
var a = moment();
var b = moment.utc();
a.format();
b.format();
a.valueOf();
b.valueOf();
In the first part, you're using it incorrectly. You've passed numeric input which would normally be interpreted as a unix timestamp, but then you've supplied a string-based format string so the number is converted to a string. The format string here is telling moment how the input is specified, but it doesn't match what you're actually parsing.
This doesn't error though, because by default moment's parser is in "forgiving" mode. You can read more about this in the docs.
The correct way to pass a timestamp into moment is with one of these:
moment(1456261200367)
moment(1456261200367).utc()
moment.utc(1456261200367)
The last two are equivalent, but the moment.utc(timestamp) form is prefered.
With any of those, all three will have the same .valueOf(), which is just the timestamp you started with. The difference is in the mode that the moment object is in. The first one is in local mode, reflecting the time zone of the computer where it's running, while the other two are in UTC mode.
This is evident when you format the output using the format function, as with other many other functions. I believe that answers your second question as well.
First off, I realize there's a million pages discussing this already. I have looked at least a hundred of them but cannot seem to make this work. My date and time is presented as a string, compiled from javascript to grab client's local time. It is formatted like this: 7/11/2015 8:34 PM.
I currently have:
Dim datetimeformated = DateTime.ParseExact(lblDateTime.Text, "MM/dd/yyyy HH:mm tt", CultureInfo.InvariantCulture)
I have tried many different variants, but this should be correct I think, yet it does not work. Any help is greatly appreciated. TIA
The correct format for your case is: M/dd/yyyy h:mm tt, and perhaps even, M/d/yyyy h:mm tt, if you can have the day of the month as a single digit.
Explanation: Why your format string didn't work.
MM: means that you must always have 2 digits for the month, clearly not the case in your example.
dd: again, means that you must always have 2 digits for the day of the month. Is that the case? Adjust the parameter if needed.
HH: This actually means that you are expecting the hour value as 2-digits using the 24-hour clock (00-23), which is clearly wrong on both accounts. You can have a single digit, and you are not using the 24-hour clock, because you are using the AM/PM designator.
Relevant documentation link: Custom Date and Time Format Strings.
On a 32 bit OS, with an Intel processor,
DateTime e.g. 2/17/2009 12:00:00 AM
Notice that it is: mm/DD//yyyy
On a 64 bit OS, with an AMD processor,
DateTime e.g. 17-02-2009 00:00:00
Now when I try to parse the 1st format, it throws an error on the 2nd platform.
That means - DateTime.Parse("2/17/2009 12:00:00 AM") - throws an error - cannot convert.
whereas, on the same platform,
DateTime.Parse("17/2/2009 12:00:00 AM") works! That means DD/MM is fine, MM/DD is not.
What is causing this? The 64-bit OS? The processor?
How do I get rid of the problem?
DateTimes themselves don't have formats. You parse them or format them into strings. (It's like numbers - integers aren't stored in hex or decimal, they're just integers. You can format them in hex or decimal, but the value itself is just a number.)
The format will depend on the culture of the operating system (or more accurately, the culture of the thread, which is typically the same as the operating system one).
Personally I like to explicitly set the format I use for either parsing or formatting, unless I'm actually displaying the string to the user and know that the culture is appropriate already.
Check your "Date and time formats" in the "Region and Language" control panel.
Also, if you want DateTime to generate a specific format, don't just call plain ToString(), but pass it a parameter indicating the format you want. Similarly, if you know the format of the date you are asking it to parse, call TryParseExact(), and tell it the format you are providing.
See also MSDN's Standard Date and Time Format Strings