Meaning of [Z] in format + string in Moment.js - momentjs

I am wondering what this does:
newM = moment("2015-08-11T13:00:00.000000Z", "YYYY-MM-DDTHH:mm:ss.SSSS[Z]", true)
Specifically - the [Z] in the format string.
I am using a library (react-bootstrap-datetimepicker) which uses moment. This library (React component) takes a parameter 'format' which is used as the second parameter to moment
I can't see what the [Z] is doing. But I have to do this rather than just 'Z' to get the result I want when I format the moment object for display with this string: newM.format('YYYY-MM-DD HH:mm:ss.SSSZ').
EDIT:
to be clear: I understand that 'Z' will cause the datetime passed to be treated as UTC, as per the docs. But what is the significance of the square brackets - which are not in the docs.

For everyone who cares about consistency due to the missing Z at the end - try to add [Z] to your format.
Example: .format('YYYY-MM-DDTHH:mm:ss[Z]') so the result is: 2019-11-26T10:39:54Z
More detailed explanation you can find in this github issue.

Z does not cause the time to be treated as UTC when used in the format. It matches a timezone specifier:
Format: Z ZZ
Example: +12:00
Description: Offset from UTC as +-HH:mm, +-HHmm, or Z
And under the documentation for format:
To escape characters in format strings, you can wrap the characters in
square brackets.
By specifying Z in brackets, you are matching a literal Z, and thus the timezone is left at moment's default, which is the local timezone.
Unless you specify a time zone offset, parsing a string will create a
date in the current time zone.
If your time is really in UTC, this is probably not desired behavior. If you want to parse it as UTC but display it in local time, use Z and then call local() on the resulting moment object, so most likely what you want is:
// Parse with timezone specifier (which is UTC here) but convert to local time
newM = moment("2015-08-11T13:00:00.000000Z", "YYYY-MM-DDTHH:mm:ss.SSSSZ", true).local();

Related

Understanding Escape characters in Unicode LDML Date Format for extended ISO 8601

While using the following control https://openui5.hana.ondemand.com/#docs/api/symbols/sap.m.DatePicker.html#setValueFormat
Supported format options are pattern-based on Unicode LDML Date Format
notation. http://unicode.org/reports/tr35/#Date_Field_Symbol_Table
<DatePicker id="date" value="{/bound/value}" valueFormat="yyyy-MM-dd'T'HH:mm:ss.SSS'Z" displayFormat="MMMM d, y"change="handleChange"/>
In the pattern, the T is escaped with ' on either side.
According to https://www.w3.org/TR/NOTE-datetime, "T" appears literally in the string, to indicate the beginning of the time element, as specified in ISO 8601.
I am confused about the usage pattern for escaping the Z at the end.
Regardless of how I escape the Z with '
on both sides valueFormat="yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"
or only in the beginning, valueFormat="yyyy-MM-dd'T'HH:mm:ss.SSS'Z",
I still get the correct value.
What is the correct usage here? I would think 'Z' would be more consistent with how 'T' is being escaped.
The Z is not a placeholder like the T. It is a designation of the timezone. If you look in the file you linked it refers to the pattern TZD to represent the designation of the timezone. This may be +1:00 or +11:00 or it may be just Z for Zulu or UTC.
Hopefully that clears it up.
valueFormat="yyyy-MM-dd'T'HH:mm:ss.SSSTZD" is what you are looking for.

How to convert a local datetime to UTC with moment.js

I've found a couple of existing StackoverFlow questions on this but nothing very definite.
I have a local datetime. I want this in UTC. my local datetime does not have a 'Z' at the end or any offset information.
I first tried:
moment(mylocaldatetime).toISOString() #works fine because this method always returns time in UTC
But for consistency with other code I didn't want to use to ISOString() so I did this:
moment(mylocaldatetime).utc().format()
This seems to work fine. If the browser running this code is in UTC + 1 I get a datetime one hour less than mylocaldatetime (with an offset string if I specify that in the format). I.e. it has treated mylocaldatetime as a local time, taken account of my current time zone, and given me my local time as UTC.
However. This appears to contradict the moment.js docs which are pretty clear that:
If you want to parse or display a moment in UTC, you can use moment.utc() instead of moment(). - Notice the 'parse'.
and
Moment normally interprets input times as local times (or UTC times if moment.utc() is used).
If these doc comments were true this line:
moment(mylocaldatetime).utc().format()
should treat mylocaldatetime as if it were utc and then output this datetime in utc - no difference. No conversion. But that is not what I get.
Maybe what this line moment(mylocaldatetime).utc().format() is saying is:
create a moment object in local mode with mylocaldatetime. Then put the moment object into utc mode. So now when we format for display we output as utc. IF this is the case I think the docs could be made clearer.

momentJS UTC versus specifying the timezone in the moment constructor

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.

How to convert the format of inserted datetime in Informix?

I insert my date/time data into a CHAR column in the format: '6/4/2015 2:08:00 PM'.
I want that this should get automatically converted to format:
'2015-06-04 14:08:00' so that it can be used in a query because the format of DATETIME is YYYY-MM-DD hh:mm:ss.fffff.
How to convert it?
Given that you've stored the data in a string format (CHAR or VARCHAR), you have to decide how to make it work as a DATETIME YEAR TO SECOND value. For computational efficiency, and for storage efficiency, it would be better to store the value as a DATETIME YEAR TO SECOND value, converting it on input and (if necessary) reconverting on output. However, if you will frequently display the value without doing computations (including comparisons or sorting) it, then maybe a rococo locale-dependent string notation is OK.
The key function for converting the string to a DATETIME value is TO_DATE. You also need to look at the TO_CHAR function because that documents the format codes that you need to use, and because you'll use that to convert a DATETIME value to your original format.
Assuming the column name is time_string, then you need to use:
TO_DATE(time_string, '%m/%d/%Y %I:%M %x') -- What goes in place of x?
to convert to a DATETIME YEAR TO SECOND — or maybe DATETIME YEAR TO MINUTE — value (which will be further manipulated as if by EXTEND as necessary).
I would personally almost certainly convert the database column to DATETIME YEAR TO SECOND and, when necessary, convert to the string format on output with TO_CHAR. The column name would now be time_value (for sake of concreteness):
TO_CHAR(time_value, '%m/%d/%Y %I:%M %x') -- What goes in place of x?
The manual pages referenced do not immediately lead to a complete specification of the format strings. I think a relevant reference is GL_DATETIME environment variable, but finding that requires more knowledge of the arcana of the Informix product set than is desirable (it is not the first thing that should spring to anyone's mind — not even mine!). If that's correct (it probably is), then one of %p and %r should be used in place of %x in my examples. I have to get Informix (re)configured on my machine to be able to test it.

Conversion from DateTime (Joda Time) to Date (java.util)

I parse this date "22/11/11" into a DateTime object called s. When I do s.getDayOfMonth() it gives me 22 which is right. However, when I convert the DateTime object to a Date object and try to get the date using s.toDate().getDate() it returns 24 which is not right. Does anyone have an idea why is this happening ?
The Joda-Time DateTime.toDate() method converts to a java.util.Date with the same millisecond instant. The java.util.Date.getDate() method uses the local default time-zone to return its value, whereas DateTime.getDayOfMonth() uses the time-zone stored in the DateTime object. If the two time-zones are different, you may see a difference, explaining the 22/24 you observe.
To understand further, print the time-zone of the DateTime, and the default Java zone TimeZone.getDefault() used by java.util.Date.

Resources