Converting to UTC is giving NaN error in Javascript - javascript

I have below code which is giving NaN error when i am trying to convert it into Date.UTC format.
let sDate = "2019, 10, 19";
let min = Date.UTC(sDate);
whereas below code is giving me correct result
let min = Date.UTC(2019, 10, 19);
but as per my need, sDate is supposed to be passed as parameter because it may vary. How to correct this?

If you refer docs, Date.UTC does not take date string as an argument. It takes individual parts.
Date.UTC(year[, month[, day[, hour[, minute[, second[, millisecond]]]]]])
So when you pass Date.UTC('2019, 10, 19'), you are just passing year's value and not other values. Year's value is also not number. Hence NaN.
If you wish to create UTC date using date string, you will have to split values.
The date arguments are not a string:
let sDate = "2019, 10, 19";
let min = Date.UTC(...sDate.split(', '));
console.log(new Date(min));

You can use String.split (with destructuring) to convert a known date string format into year, month, day. You have do subtract 1 from the month value when passing to the Date.UTC function since this accepts a month value from 0 to 11 (January to December).
If you want to do more sophisticated Date parsing I strongly recommend you use a library such as Moment.js. This is well tested and has a very flexible API.
const sDate = "2019, 10, 19";
const [year, month, day] = sDate.split(",");
console.log("Date components:", {year, month, day});
// Date constructor takes a month from 0: January to 11: December
const utcDate = Date.UTC(year, month - 1, day);
console.log("Date (ISO):", new Date(utcDate).toISOString());
console.log("Date (toLocaleString):", new Date(utcDate).toLocaleString("en", { timeZone: "UTC"}));

The Date.UTC() method accepts parameters similar to the Date constructor but treats them as UTC
Date.UTC(year[, month[, day[, hour[, minute[, second[, millisecond]]]]]])
you can't use string directly
getData=(d)=>{
return [d.getFullYear(),d.getMonth(),d.getDate(), d.getHours(),d.getMinutes()];
};
let splited = getData(new Date('2019, 10, 19'))
console.log(new Date(Date.UTC(...splited)));

Related

How to get date string from day number and month number using moment?

dayNumber: 28,
monthNumber: 2,
expected output using moment "2022-02-28"
What I've tried const date = moment() .month(monthNumber) .days(dayNumber) .format("YYYY-MM-DD");
but that gives me something like "2022-03-17"
what am I doing wrong?
You have two errors in your code:
The first one is that you need to replace the days function call with date
The second one is that the argument of the month function starts from 0. So 0 is January, 1 is February etc.
So, what you need to do in order to get 2022-02-28 is the following:
const date = moment() .month(1) .date(28) .format("YYYY-MM-DD");
.month expects values from 0-11. See: https://momentjs.com/docs/#/get-set/month/
.days is day of week, .date is day of month. See: https://momentjs.com/docs/#/get-set/day/ and https://momentjs.com/docs/#/get-set/date/
const date = moment().month(monthNumber-1).date(dayNumber).format("YYYY-MM-DD");
You can also create a moment instance with an array of numbers that mirror the parameters passed to new Date(), e.g. [year, month, day].
See moment/parsing/array
NB: Month is zero-indexed.
const year = 2022;
const monthNumber = 2;
const dayNumber = 28;
console.log(moment([year, monthNumber - 1, dayNumber]).format('YYYY-MM-DD'))
<script src="https://momentjs.com/downloads/moment.js"></script>

Date parsing from different formats?

I have a string, which can come in different formats:
01.01.2020
01/01/2020
01-01-2020
or
2020-01-01
2020.01.01
2020/01/01
Now if I try doing
const date = new Date(myDateString);
I will in some cases get an error "Invalid Date".
How can I cover all scenarios and transform any scenario into a valid date?
It seems like the new Date(), only takes the format Y-m-y?, even though the other cases are also "valid" dates?
You can moment to do that. But you need to know which format is used.
https://stackoverflow.com/a/44134515/3573340
Date() constructor is accurate if it's parameters are YYYY, MM, DD. The dates of Jan 1, 2020 should go like this:
new Date(2020, 0, 1) // Month is 0 index, so MM -1
Given an array of strings .map() and split() each by .-/ delimitters, resulting in sub-arrays of 3 strings from each string:
strArr.map(str => str.split(/[-./]/))
then .flatMap() to catch any array that starts with 2 digits and .reverse() it:
.flatMap(sub => sub[0].length === 2 ? [sub.reverse()] : [sub])
Finally, .flatMap() each sub-array into the Date() constructor:
.flatMap(sub => [new Date(+sub[0], +sub[1] - 1, +sub[2])])
const jan1_2020 = [
`01.01.2020`,
`01/01/2020`,
`01-01-2020`,
`2020-01-01`,
`2020.01.01`,
`2020/01/01`
];
const formatDate = strArr => strArr.map(str => str.split(/[-./]/)).flatMap(sub => sub[0].length === 2 ? [sub.reverse()] : [sub]).flatMap(sub => [new Date(+sub[0], +sub[1] - 1, +sub[2])]);
let x = formatDate(jan1_2020);
console.log(x);
You can split the string on the known delimiters and then see whether the first part has four digits. If so, you know it's year-month-day. If not, you know it's month-day-year. You can then construct the date accordingly:
const dateStrings = [
"10.31.2020",
"10/31/2020",
"10-31-2020",
"2020-10-31",
"2020.10.31",
"2020/10/31",
]
function parseDateStr(str) {
// split on dots, dashes, and slashes
const parts = str.split(/[./-]/);
// mm-dd-yyyy
const [year, month, day] = parts[0].length > 2 ? parts : [parts[2], parts[0], parts[1]];
// alternate for dd-mm-yyyy
// const [year, month, day] = parts[0].length > 2 ? parts : parts.reverse();
// construct and return the date. (month is 0 based)
return new Date(year, month - 1, day);
}
const results = dateStrings.map(parseDateStr);
console.log(results);
JavaScript will parse the dates in following formats:
ISO Date - YYYY-MM-DD
Short Date - YYYY/MM/DD
Long Date - Jan 01 2022
Some other versions of the dates also might also work but the best practice is to limiting your formats to ISO format. For more on js date formats refer this

Calculate datetime correctly in UTC from date string

I'm trying to calculate the datetime in UTC, i have the bellow code and using Luxon
weeklyDish.orderBeforeTime = timeZoneToUTC(
"Europe/Amsterdam",
year,
month,
day,
hours
);
function timeZoneToUTC(timezone, year, month, day, hours) {
const dateObj = `${year}-${month}-${day} ${hours}:00`;
const datetime = DateTime.fromFormat(dateObj, "yyyy-M-d H:mm", {
zone: timezone,
});
return datetime.toUTC().toString();
}
The code above always return the wrong hour.
How can I get the year, month, hour and return a UTC string to save in the DB?
I'm going to be migrating data that has date as string (example: "2020-12-13"), how can I convert it to UTC date and subtract days correctly?
You need to show an example to demonstrate your issue. The following shows use of Luxon's UTC and setZone methods that both seem to correctly convert a date set for "Europe/Amsterdam".
Note that the string passed to DateTime.fromISO must form a valid ISO 8601 timestamp like YYYY-MM-DDTHH.
let DateTime = luxon.DateTime;
let [tz, y, m, d, h] = ["Europe/Amsterdam", '2020', '11', '30', '12'];
let date = DateTime.fromISO(`${y}-${m}-${d}T${h}`, { zone: "Europe/Amsterdam" });
console.log(tz + '\n' + date.toString());
let dateUTC = date.setZone('UTC');
console.log('setZone to UTC\n' + dateUTC.toString());
let dateUTC2 = date.toUTC();
console.log('toUTC method\n' + dateUTC2.toString());
<script src="https://cdn.jsdelivr.net/npm/luxon#1.25.0/build/global/luxon.min.js"></script>
PS Amsterdam standard time is +1, daylight saving time is +2.
If the date is already parsed, you can use the date constructor directly. However, the constructor depends on the local timezone, luckily you can use Date.UTC instead.
The tricky part is about the timezone, which is not supported in the constructor, but it's a simple addition anyway.
So I'd wager something like so should work:
function timeZoneToUTC(timezone, year, month, day, hours) {
return new Date(Date.UTC(year, month - 1, day, hours + timezone));
}
Note: the month parameter is an index (0-based), so if you have 1=January, you need to decrease your month by one (as in my example).
Edit: uh, apparently, Date.UTC returns a timestamp, so you need to use the constructor anyway.

What the elegant way to convert date in string to Date object?

I have this date in string format:
"05/2016" or "12/2015"
How can I convert the dates above in string format to Date() javascript object?
Date constructor accepts params in next order: year, month, day, hours, minutes, seconds, milliseconds, so simply parse string and pass it into Date constructor.
var data = "05/2016".split('/');
// Add + before year to convert str into number. Decrease second param because month starts from 0..11.
var date = new Date(+data[1],data[0] - 1);
console.log(date);
Also, you can convert your string to format which would be parsed correctly by new Date ( See more about dateString in MDN Date.parse description.
// convert string "05/2016" -> "2016-05"
var dateString = "05/2016".split('/').reverse().join('-');
var date = new Date(dateString);
console.log(date);
The previous answers are not correct - they get either the month or the year wrong. This is right (see the comment by Frédéric Hamidi)
var str = "12/2015";
var arr = str.split('/');
var date = new Date(parseInt(arr[1], 10), parseInt(arr[0], 10)-1)
console.log(date)
You can split string to get an array then use Date constructor.
new Date(year, month[, day[, hour[, minutes[, seconds[, milliseconds]]]]]);
var str = "12/2015";
var arr = str.split('/');
var date = new Date(parseInt(arr[1], 10), parseInt(arr[0], 10) - 1)
console.log(date)
You might want to look at Converting string to date in js
I had a similar issue and stumbled upon this existing link.

Javascript to compare two dates, from strings, begin <= end

I get two strings formated like (Brazilian Format): "DD/MM/YYYY", I need to compare both. Since the first field is the begin and the last is the end,
My validation is begin <= end
Date.new(begin) is generating 'invalid date' even on ISO !
Don't use Date.new. Use new Date(). Because of the format of your date string, I would recommend grabbing each field individually and passing them into the constructor:
var startYear = parseInt(document.getElementById('startYear'), 10);
var startMonth = parseInt(document.getElementById('startMonth'), 10) - 1; // as per Residuum's comment
var startDay = parseInt(document.getElementById('startDay'), 10);
var start = new Date(startYear, startMonth, startDay);
etc. If you're handed a date string, then you can use fuzzy lollipop's method to get each field from the string. I'm not sure if the Date constructor will accept unparsed strings for the individual fields, however.
The, once you have the two dates you'd like to compare, just compare their values in milliseconds since the epoch:
function isValid(start, end) {
return start.getTime() < end.getTime();
}
There's a nice date handling library called datejs which has a parseExact(dateStr, format) method.
you can do this, if you know your date will always be formatted the same way dd/mm/yyyy
today = "23/02/1001";
dateComponents = today.split("/");
date = new Date(dateComponents[2], dateComponents[1] - 1, dateComponents[0]);
but a better solutions is to look at this page there is Datejs which is a good alternative to date processing.
Quick 'n dirty :
function is_valid (start , end) {
return start.split('/').reverse().join('') <= end.split('/').reverse().join('') ;
}
That is, split the date into components, reverse the order join them again and do a string comparison.
Edit: As noted in the comment, of course this won't work if your month/days smaller than 10 are not zero padded.
The new 'hotness' in JS time world: http://momentjs.com/
Fits this use-case as well
Here are all available constructors for date objects in Javascript:
dateobject = new Date(); // returns date of current time stamp
// on the browser
dateobject = new Date("Month Day, Year Hours:Minutes:Seconds");
dateobject = new Date(Year, Month, Day);
dateobject = new Date(Year, Month, Day, Hours, Minutes, Seconds);
dateobject = new Date(Milliseconds);
Pick the one you try to use, but I would go for new Date(Year, Month, Day); in your case.
EDIT:
Note: Monthis zero-based in Javascript, so January 1 2010, will be new Date(2010, 0, 1) and December 31 2011 is new Date(2010, 11, 31).

Categories