Moment and date-fns formatting date incorrect - javascript

I have been trying to format a zulu format date to normal date i.e. MM/dd/yyyy, so far I have tried date-fns and moment. The date I have is 2022-11-03T19:48:24Z I am expecting it to be formatted as 11/03/2022 but I am getting 11/04/2022, I do not understand why it is adding a day to the date and how can I fix this ?
export function fDate(
date: Date | string | number,
template: string = 'MM/dd/yyyy'
) {
return format(new Date(date), template);
}
fDate('2022-11-03T19:48:24Z')
expected outcome 11/03/2022 but getting 11/04/2022
format is coming from date-fns

Do not use the Date constructor to parse a date_time string when you are using a library like moment.js or date-fns. Instead, use the applicable constructor or methods in the library you want to use.
moment.js
The symbols posted in your question do not match the required symbols. The symbols, d and D have different meanings. The same is the case with y and Y. Check the documentation page at https://momentjs.com/docs/
The following code produces the correct result as 11/03/2022.
var moment = require('moment');
console.log(moment("2022-11-03T19:48:24Z").format('MM/DD/YYYY'));
In your code, this will be implemented as
return moment(date).format('MM/DD/YYYY');
date-fns
The symbols posted in your question match the required symbols.
The following code produces the correct result as 11/03/2022.
const fns = require('date-fns')
console.log(fns.format(fns.parseISO('2022-11-03T19:48:24Z'), 'MM/dd/yyyy'))
In your code, this will be implemented as
return fns.format(fns.parseISO(date), 'MM/dd/yyyy');

Using moment's parseZone helped me
export function fDateISOStringToDate(
date: string,
template: string = "MM/DD/YYYY"
) {
return moment.parseZone(date).format(template);
}

Related

How to convert to date-fns?

I have following moment expression:
<DialogContent>
{startDate ? (
<DateTimePicker
value={startDate}
onChange={(value: any) =>
setStartDate(moment(value).format())
I would like to convert to date-fns format, but it fails, it is always 1970 something, why? I converted like this:
setStartDate(getUnixTime(new Date(value)))
You can import format function from date-fns and use it:
import { format } from 'date-fns';
// Pass desired format as a second parameter
setStartDate(format(value, 'yyyy-MM-dd'));
moment(value).format() return a ISO 8601 date string, look like: 2021-11-10T10:19:09+09:00. Then, I guess the setStartDate function require a date string with ISO 8601 format.
The goal is using date-fns to create a string as the result of moment.format.
To do that, you need to create a date object. If it works with moment(value) syntax, mean value is a millisecond timestamp number (1636507295498) or a formal date string (2021-11-10). Then you can create a date object by Date constructor:
new Date(value);
Now, you can use formatISO to create the required date string:
formatISO(dateObject);
The final look will be like this:
setStartDate(formatISO(new Date(value)))

Is there an equivalent to moment timezone with a Javascript date?

I have this method below that takes in a Javascript date and then has to use Moment js to do its timezone conversion.
QUESTION - Is there a way to accomplish this without moment, just using a JS Date?
// ex. (someDate, 'America/Los_Angeles', 'MMM DD # h:mm A z')
transform(dateUtc: Date, timeZone: string, momentFormat: string): string {
const tempDateUtc = moment(dateUtc).utc(true);
tempDateUtc.tz(timeZone);
return tempDateUtc.format(momentFormat);
}
To apply specific date formatting, rather than a locale based format, then no, not really, but it is possible to get the localized date parts to create a custom format.
As #RobG mentioned, you can use the Intl.DateTimeFormat to create a formatter. You build your options, including your timezone, and then use it's formatToParts(date) method to get the parts you need to construct your output.
Of course, this only works well if your Date is constructed using an epoch or UTC value.

How to format date with date-fns?

I've been trying to format a date using date-fns but I keep failing. Basically I have it working just fine with momentJS but not with date-fns:
Here's my date:
"10-13-20" // month, day, and year
Now with momentJS it works just fine like this:
let result = moment("10-13-20", 'MM-DD-YY').format()
// result = "2020-10-13T00:00:00-06:00"
So I'm trying to do the same using date-fns but no luck. Can anyone point me in the right direction? Thanks in advance!
let result = format(new Date("10-13-20"), 'MM-DD-YY') // Not working
As you can see, with moment lib, we need 2 steps to get the result: parse string to Date object, then format date object to string.
Your code - format(new Date("10-13-20"), 'MM-DD-YY') is format step, try convert a date object to a string with format template is MM-DD-YY. But your date object is not correct.
The solution is doing the same with moment lib:
Parse date string to date object. Use parse
const dateString = '10-13-20';
const date = parse(dateString, 'MM-dd-yy', new Date()) // not MM-DD-YY
Format date object to result string. Use format
const result = format(date, "yyyy-MM-dd'T'HH:mm:ss.SSSxxx")
console.log(result)
Result will be like (the same with moment's result in my timezone):
2020-10-13T00:00:00.000+09:00
const date = "2021-12-20"
console.log(format(parseISO(date), "dd-MM-yyyy"));
// output: 20-12-2021

Weird ISO formatted Datestring to Javascript Date

I've got a Datestring like this one: 20171010T022902.000Z and I need to create Javascript Date from this string. new Date('20171010T022902.000Z') would return Invalid Date.
I saw that it's possible to use moment.js for this purpose but I am not sure how I would specify the according format for my given example. I found this example from another thread:
var momentDate = moment('1890-09-30T23:59:59+01:16:20', 'YYYY-MM-DDTHH:mm:ss+-HH:mm:ss');
var jsDate = momentDate.toDate();
Question:
How can I create a JavaScript date from a given Datestring in this format: 20171010T022902.000Z (using moment)?
Your input (20171010T022902.000Z) matches known ISO 8601 so you can simply use moment(String) parsing method. In the Supported ISO 8601 strings section of the docs you will find:
20130208T080910.123 # Short date and time up to ms
Then you can use toDate() method
To get a copy of the native Date object that Moment.js wraps
Your code could be like the following
var m = moment('20171010T022902.000Z');
console.log( m.format() );
console.log( m.toDate() );
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.min.js"></script>
Note that this code does not shows Deprecation Warning (cited in Bergi's comment) because you input is in ISO 8601 known format. See this guide to know more about this warning.
Moreover "By default, moment parses and displays in local time" as stated here so format() will show the local value for your UTC input (20171010T022902.000Z ends with Z). See moment.utc(), utc() and Local vs UTC vs Offset guide to learn more about moment UTC mode.
I think you can do this without moment.js,.
Basically extract the parts you need using regex's capture groups, and then re-arrange into a correct format for new Date to work with.
var dtstr = '20171010T022902.000Z';
var dt = new Date(
dtstr.replace(/^(\d{4})(\d{2})(\d{2})T(\d{2})(\d{2})(\d{2})(\.\d{3}Z)$/,
"$1-$2-$3T$4:$5:$6$7"));
console.log(dt);
console.log(dt.toString());
If you are using moment.js anyway, this should work ->
var dt = moment("20171010T022902.000Z", "YYYYMMDDTHHmmss.SSSSZ");
console.log(dt.toString());
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.19.1/moment.min.js"></script>

Parse this value with moment doesn't work

I have a date value like this value.game_date = 2013-10-27 03:39:35 and I'm trying to parse it as follow:
moment().format(value.game_date, 'DD-MM-YYYY');
But I get this as result 29-10-2013 00:00:00 where I'm looking for this format: 29-10-10-29 without hour, what I'm doing wrong?
I think you have some typos or misinformation in your post regarding the output you're getting and what you're desiring.
Based on what appears to be a misunderstanding of moment, however, I am pretty sure that what you want is:
value.game_date = '2013-10-27 03:39:35';
var formatted_game_date = moment(value.game_date).format('DD-MM-YYYY');
// produces '27-10-2013'
moment() is a factory function which takes a date string and returns a moment instance. That moment instance then has various methods available, such as format() which takes a format string as the first param.
So your code is producing a moment instance representing current date/time (because you're not passing any params to moment()), then you ask .format() to return a string formatted using your date stamp as the formatter. Your date string doesn't have any of the things in it which format would parse and replace, so you just get back your date string.
The code I gave passes the date string to moment to produce the instance, then asks .format() for a formatted string using your desired format template.

Categories