conversion of an object to UTC ISO time format - javascript

I have an object with time information.
const dateTime = {
day: 3,
hour: 18,
minute: 22,
month: 11,
second: 54,
timeZoneOffset: -60,
year: 2022
}
How do I convert this object to ISO UTC time format?

The Date API allows to build a date object with all your arguments.
You'd have to create a new Date object with your value, and then you can convert your object to the format you want (UTC ISO string...).
If the timezone is not the timezone of the locale machine, you'd have to workaround with the setTime method.
see
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date
Also see this answer for more info about setting time zone
const dateTime = {
day: 3,
hour: 18,
minute: 22,
month: 11,
second: 54,
timeZoneOffset: -60,
year: 2022
};
const {
day,
hour,
minute,
month,
second,
year,
timeZoneOffset
} = dateTime;
const d = new Date(Date.UTC(year, month, day, hour, minute, second));
d.setTime(d.getTime() + timeZoneOffset * 60000);
console.log(d.toISOString());
console.log(d.toUTCString());

Related

Generating 7 days in a week as formatted object

so I am using the momentJS library as the moment to create an array of 7 days in a week like this:
const moment = require('moment')
var startOfWeek = moment().startOf('week');
var endOfWeek = moment().endOf('week');
var days = [];
var day = startOfWeek;
while (day <= endOfWeek) {
days.push(day.format("MMMM ddd DD, YYYY "));
day = day.clone().add(1, 'd');
}
console.log(days);
And the result return an array of 7 days a week like this:
["December Sun 25, 2022 ","December Mon 26, 2022 ", "December Tue 27, 2022 " , "December Wed 28, 2022 ", "December Thu 29, 2022 ", "December Fri 30, 2022 ", "December Sat 31, 2022 "]
But the result that I look for is something like this:
const weekday = [
{
day: Mon,
date: 26
},
{
day: Tue,
date: 27
},
{
day: Wed,
date: 28
},
{
day: Thu,
date: 26
},
{
day: Fri,
date: 26
},
{
day: Sat,
date: 26
},
]
I am stuck on how to convert the data, could anyone able to help me ? Thanks
Without momentjs, you can use toLocaleDateString and other native Date methods to achieve the result:
const day = new Date(); // Today
day.setDate(day.getDate() - day.getDay() - 1); // Most recent Saturday (not today)
const weekday = Array.from({length: 7}, () => (
day.setDate(day.getDate() + 1), {
day: day.toLocaleDateString("en-US", { weekday: "short" }),
date: day.getDate(),
}
));
console.log(weekday);
If you wish to keep the original output to use elsewhere and not modify the original code, you can map over the days array and construct a new array based on the formatted string (converting to an integer as necessary).
const days = ["December Sun 25, 2022 ", "December Mon 26, 2022 ", "December Tue 27, 2022 ", "December Wed 28, 2022 ", "December Thu 29, 2022 ", "December Fri 30, 2022 ", "December Sat 31, 2022 "]
const weekday = days.map((formattedDate) => {
const [_, day, dateString] = formattedDate.split(" ");
return {
day,
date: parseInt(dateString)
};
});
console.log(weekday);
Alternatively, you can modify your original code
//const moment = require('moment')
const startOfWeek = moment().startOf('week');
const endOfWeek = moment().endOf('week');
// uncomment if you still want `days`
// const days = [];
const weekday = [];
let day = startOfWeek;
while (day <= endOfWeek) {
// days.push(day.format("MMMM ddd DD, YYYY "));
weekday.push({ day: day.format("ddd"), date: day.date() });
day = day.clone().add(1, 'd');
}
console.log(weekday);
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.4/moment.min.js"></script>

Passing options argument to The toLocaleString() method removes the time portion from the output

I want to convert a UTC timestamp to mm/dd/yyyy hh:mm:ss format in Javascript.
timestamp = '1645199199.241098'
const d1 = new Date(parseInt(timestamp) * 1000)
.toLocaleString("en-US",
{
hour12:false,
timeZone: 'America/Chicago',
});
console.log(d1)
This code above does not give me two digit months and days. Setting the options for 2-digit month and day gives me the correct date format but removes the time from the output all together.
timestamp = '1645199199.241098'
const d2 = new Date(parseInt(timestamp) * 1000)
.toLocaleString("en-US",
{hour12:false,
timeZone: 'America/Chicago',
year: 'numeric',
month: '2-digit',
day: '2-digit'
});
console.log(d2);
How do I retain the time and get the date in the desired format in my output?
When you start specifying what parts you want to have in the string, the rest of them default to being absent. If you want the time, you need to tell it that:
const timestamp = "1645199199.241098"
const d2 = new Date(parseInt(timestamp) * 1000)
.toLocaleString("en-US", {
hour12: false,
timeZone: "America/Chicago",
year: "numeric",
month: "2-digit",
day: "2-digit",
hour: "numeric", // ***
minute: "numeric", // ***
second: "numeric", // ***
});
console.log(d2);
You can add the remaining options for hour, minute, and second:
const timestamp = '1645199199.241098';
const d2 = new Date(parseInt(timestamp) * 1000)
.toLocaleString("en-US", {
hour12: false,
timeZone: 'America/Chicago',
year: 'numeric',
month: '2-digit',
day: '2-digit',
hour: '2-digit',
minute: '2-digit',
second: '2-digit'
});
console.log(d2);
Documentation regarding available options and value format values:
https://tc39.es/ecma402/#sec-datetimeformat-abstracts

Why is momentjs converting the time zone the wrong way?

I have a form that schedules events. Part of the form is setting the event start time. The form has selection fields for Date, Time, and Timezone. I use this information with momentJS to build a dateTime called eventTime. The form should not submit if the selected DateTime is in the past. So I wrote some simple logic that says:
timeDiff = moment(eventTime).diff(currentTime).
If timeDiff is less than zero the no submit.(More below) This is fine but I am having issues with timezones. So here is what I am trying to do:
If I currently reside in EST and it is 2:00pm then my form should not submit if select 1:45 EST on the given day. But if I change the "Time Zone" dropdown to "Central Time" Then it should submit. Assuming I am not thinking incorrectly
1:45 CST = 2:45 EST
Therefore since it is currently 2:00 CST the form should submit, but momentJS is going the other way and it is thinking the time is 1:45 EST. Based on the moment objects below (in UTC time) I would expect "Central Zone Moment Object" to be Thu Jun 25 2020 10: 45: 00 GMT instead of Thu Jun 25 2020 08: 45: 00 GMT what am I missing.
Thanks
let date = "2020-06-25";
let time = "13:45";
let timezoneEST = "America/New_York";
let timezoneCST = "America/Chicago";
let currentTime = moment().tz(moment.tz.guess());
let eventTimeEST = moment.tz(moment(date).set({ "hour": time.substring(0, 2), "minute": time.substring(3, 5) }), timezoneEST);
let eventTimeCST = moment.tz(moment(date).set({ "hour": time.substring(0, 2), "minute": time.substring(3, 5) }), timezoneCST);
timeDiff = moment([eventTimeEST or eventTimeCST]).diff(currentTime)
if (timeDiff > 0) {
// allow submit
}
console.log(eventTimeEST)
// Eastern Zone Moment Object
// {
// _isAMomentObject: true
// _d: Thu Jun 25 2020 09: 45: 00 GMT - 0400(Eastern Daylight Time)
// _i: Thu Jun 25 2020 00: 00: 00 GMT - 0400(Eastern Daylight Time)
// _isAMomentObject: true
// _isUTC: true
// _isValid: true
// _locale: Locale { _calendar: { … }, _longDateFormat: { … }, _invalidDate: "Invalid date", _dayOfMonthOrdinalParse: /\d{1,2}(th|st|nd|rd)/, ordinal: ƒ, … }
// _offset: -240
// _pf: { empty: false, unusedTokens: Array(0), unusedInput: Array(0), overflow: -2, charsLeftOver: 0, … }
// _z: Zone { name: "America/New_York", abbrs: Array(236), untils: Array(236), offsets: Array(236), population: 21000000 }
// }
console.log(eventTimeCST)
// Central Zone Moment Object
// {
// _isAMomentObject: true
// _d: Thu Jun 25 2020 08: 45: 00 GMT - 0400(Eastern Daylight Time)
// _i: Thu Jun 25 2020 00: 00: 00 GMT - 0400(Eastern Daylight Time)
// _isAMomentObject: true
// _isUTC: true
// _isValid: true
// _locale: Locale { _calendar: { … }, _longDateFormat: { … }, _invalidDate: "Invalid date", _dayOfMonthOrdinalParse: /\d{1,2}(th|st|nd|rd)/, ordinal: ƒ, … }
// _offset: -240
// _pf: { empty: false, unusedTokens: Array(0), unusedInput: Array(0), overflow: -2, charsLeftOver: 0, … }
// _z: Zone { name: "America/New_York", abbrs: Array(236), untils: Array(236), offsets: Array(236), population: 21000000 }
// }
console.log(currentTime)
// Current Time(EST) Moment Object
// {
// _d: Thu Jun 25 2020 09: 00: GMT - 0400(Eastern Daylight Time)
// _isAMomentObject: true
// _isUTC: true
// _isValid: true
// _locale: Locale { _calendar: { … }, _longDateFormat: { … }, _invalidDate: "Invalid date", _dayOfMonthOrdinalParse: /\d{1,2}(th|st|nd|rd)/, ordinal: ƒ, … }
// _offset: -240
// _pf: { empty: false, unusedTokens: Array(0), unusedInput: Array(0), overflow: -2, charsLeftOver: 0, … }
// _z: Zone { name: "America/New_York", abbrs: Array(236), untils: Array(236), offsets: Array(236), population: 21000000 }
// __proto__: Object
// }
let currentTime = moment().tz(moment.tz.guess());
let eventTimeEST = moment.tz(moment(date).set({ "hour": time.substring(0, 2), "minute": time.substring(3, 5) }), timezoneEST);
let eventTimeCST = moment.tz(moment(date).set({ "hour": time.substring(0, 2), "minute": time.substring(3, 5) }), timezoneCST);
This code is basically setting a date in your current TZ and then translating it into another timezone (America/New York-America/Chicago).
The second statement is basically doing EDT to EDT.
The third statement is doing EDT to CDT.
That's why it goes back an hour. Because 1:45 PM EDT is 12:45 PM CDT.
But what you really want to do is to get the time at that timezone.
Eg. 1:45 PM CDT.
The way you do it is by basically setting the time on that timezone.
let date = "2020-06-25";
let timezoneEDT = "America/New_York";
let timezoneCDT = "America/Chicago";
let notBefore = { hour : 14, minute : 0 };
let clock = { hour : 13, minute : 45 };
let a = moment(date).tz(timezoneEDT).set(notBefore); //14:00 EDT
let b = moment(date).tz(timezoneCDT).set(clock); //13:45 CDT -> 14:45 EDT
let c = moment(date).tz(timezoneEDT).set(clock); //13:45 EDT
console.log(test(a, b)); //14:00 EDT against 14:45 EDT prints valid
console.log(test(a, c)); //13:45 EDT against 14:00 EDT prints invalid
function test(a,b){
return a.diff(b) > 0 ? 'Invalid date' : 'Valid date';
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.27.0/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment-timezone/0.5.31/moment-timezone-with-data-2012-2022.js"></script>
As expected
let eventTimeCST = moment.tz(moment(date).set({ "hour": time.substring(0, 2), "minute": time.substring(3, 5) }), timezoneCST);
creates a moment object in my timezone (EST) and the .tz adjusts that time zone. I needed to create a new moment object in the CST timeZone, compare it to my timezone.
That can be achieved like;
let eventTimeCST = moment.tz({'year': 2020, 'month': 06, 'day': 26, 'hour': 9, 'minute': 30}, timezoneCST)
So I just parsed out date and time and built the object.
FYI replacing
{'year': 2020, 'month': 06, 'day': 26, 'hour': 9, 'minute': 30}
with
date + " " time
also worked but threw a deprecation warning

Get week day of current time in specified time zone

I need to get the week day of the current time in a specified timezone, and without using libraries. Numbered week days or strings are both fine.
I've used this approach to switch timezone:
new Date().toLocaleString("en-US", {timeZone: "America/Chicago"})
but the output is a string so I can't do date logic in it.
PS: I am on Google Apps Script, which is why I mentioned no libraries.
you can use special options for that:
{ weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' };
to show a week day:
new Date().toLocaleString('en-US', {day: '2-digit', timeZone: 'America/Chicago' })
or to show full day name:
new Date().toLocaleString('en-US', {weekday: 'long', timeZone: 'America/Chicago' })
I am suggesting you use the Intl.DateTimeFormat
const formatter = new Intl.DateTimeFormat('en-US', {
timeZone: "America/Chicago",
weekday: 'long',
})
console.log(formatter.formatToParts(new Date()))
// you get an array like : [{type: "weekday", value: "Friday"}]
You can use the Moment for this. It gives weekdays from local.
moment.months()
moment.monthsShort()
moment.weekdays()
moment.weekdaysShort()
moment.weekdaysMin()
It is sometimes useful to get the list of months or weekdays in a locale, for example when populating a dropdown menu.
moment.months();
Returns the list of months in the current locale.
[ 'January',
'February',
'March',
'April',
'May',
'June',
'July',
'August',
'September',
'October',
'November',
'December' ]
Similarly, moment.monthsShort returns abbreviated month names, and moment.weekdays, moment.weekdaysShort, moment.weekdaysMin return lists of weekdays.
You can pass an integer into each of those functions to get a specific month or weekday.
moment.weekdays(3); // 'Wednesday'
As of 2.13.0 you can pass a bool as the first parameter of the weekday functions. If true, the weekdays will be returned in locale specific order. For instance, in the Arabic locale, Saturday is the first day of the week, thus:
moment.locale('ar');
moment.weekdays(true); // lists weekdays Saturday-Friday in Arabic
moment.weekdays(true, 2); //will result in Monday in Arabic

How to use diff method in Luxon

I currently get a date from calendar control and using luxon I add days, minutes to it and change it to LongHours format like below:
newValue : is value i get from frontend(calendar control)
let formattedDate: any;
FormattedDate = DateTime.fromJSDate(new Date(newValue)).plus({ days: 1, hours: 3, minutes: 13, seconds: 10 }).toLocaleString(DateTime.DATETIME_HUGE_WITH_SECONDS)
console.log(formattedDate);
const formattedDateParsed = DateTime.fromJSDate(new Date(formattedDate));
const newValueParsed = DateTime.fromJSDate(new Date(newValue));
var diffInMonths = formattedDateParsed.diff(newValueParsed, ['months', 'days', 'hours', 'minutes', 'seconds']);
diffInMonths.toObject(); //=> { months: 1 }
console.log(diffInMonths.toObject());
Currently the formattedDateParsed is coming as 'Null'
Can I get some help as how to parse the date so that diff can be calculated
A few things going on here.
First, FormattedDate and formattedDate are different variables, so formattedDate isn't being set:
let formattedDate: any;
FormattedDate = DateTime.fromJSDate(new Date(newValue)).plus({ days: 1, hours: 3, minutes: 13, seconds: 10 }).toLocaleString(DateTime.DATETIME_HUGE_WITH_SECONDS)
console.log(formattedDate);
Second, you are converting to a string and then back into a DateTime, using the Date constructor as a parser, which isn't a great idea because a) it's unnecessary, and b) browsers aren't super consistent about which strings they can parse.
Instead, let's just convert once:
const newValueParsed = DateTime.fromJSDate(new Date(newValue));
const laterDate = newValueParsed.plus({ days: 1, hours: 3, minutes: 13, seconds: 10 });
const diffInMonths = laterDate.diff(newValueParsed, ['months', 'days', 'hours', 'minutes', 'seconds']);
diffInMonths.toObject(); // => {months: 0, days: 1, hours: 3, minutes: 13, seconds: 10}

Categories