Date manipulation issues/questions using AngularJS and MomentJS - angularjs

I'm using a datepicker and a timepicker to have a user choose a specific date and time. In my controller, I intend to combine the selected date and the selected time.
I'm using the most current production versions of AngularJS, Bootstrap, Angular UI-Boostrap, and MomentJS. I have the latest Angular-Moment added too, but not sure if/how it might help address the issues noted below.
I'd use a datetimepicker, but there's too many to choose from and not
a lot of time to figure out which one does everything I need
(validation, masking, bootstrap v3, dependency on other datetimepickers, etc.).
In my app I have included and successfully used MomentJS for other purposes, but in this case, I'm having an issue where the datepicker and the timepicker are each returning the correct value, but MomentJS is returning the wrong value when I load those dates/times into a moment() object.
Here's some examples of what I'm running into... First BeginDate, and EndDate values are coming from the Angular UI-Bootstrap DatePicker. BeginTime and EndTime are coming from the TimePicker of the same library.
DatePicker and TimePicker examples
<!-- datepicker nearly mirrors the example on the ui-bootstrap docs -->
<uib-timepicker ng-model="task.BeginTime" ng-change="TimeChanged()" hour-step="hourSteps" minute-step="minuteSteps" show-meridian="true" required></uib-timepicker>
JS console output examples
// returns correct value: Wed Nov 04 2015 00:00:00 GMT-0800 (Pacific Standard Time)
console.log("$scope.task.BeginDate = " + $scope.task.BeginDate.toString());
// 11/04/2015 selected
// returns correct value: Sat Oct 31 2015 08:00:52 GMT-0700 (Pacific Daylight Time)
console.log("$scope.task.BeginTime = " + $scope.task.BeginTime.toString());
// 08:00 PM selected
// returns correct value: Wed Nov 04 2015 00:00:00 GMT-0800 (Pacific Standard Time)
console.log("$scope.task.EndDate = " + $scope.task.EndDate.toString());
// 11/04/2015 selected
// returns correct value: Sat Oct 31 2015 09:00:52 GMT-0700 (Pacific Daylight Time)
console.log("$scope.task.EndTime = " + $scope.task.EndTime.toString());
// 09:00 PM selected
This situation gets worse when I involve MomentJS to help me parse and concatenate the dates and times. (I've tried with and without .toString(). The next lines in my test are as follows:
// returns: 04/20/2015
var beginDate = moment($scope.task.BeginDate.toString(), "MM/DD/YYYY");
console.log("beginDate = " + beginDate.format("MM/DD/YYYY"));
// returns: Invalid date
var beginTime = moment($scope.task.BeginTime.toString(), "HH:mm A");
console.log("beginTime = " + beginTime.format("HH:mm A"));
// returns: 04/20/2015
var endDate = moment($scope.task.EndDate.toString(), "MM/DD/YYYY");
console.log("endDate = " + endDate.format("MM/DD/YYYY"));
// returns: Invalid date
var endTime = moment($scope.task.EndTime.toString(), "HH:mm A");
console.log("endTime = " + endTime.format("HH:mm A"));
If I combine the dates and times right now, I'll of course get 04/20/2015 00:00 AM returned.
Why are the dates being changed to be 8 months earlier?
Why are the times an invalid date after being loaded into MomentJS?
How do you proposed I fix this?
Why in the world does JavaScript make dates and times so difficult to work with? (I can Google that one later - just venting.)

I think perhaps the Moment syntax is off a bit. Try something like this:
var beginDate = moment($scope.task.BeginDate.toString()).format("MM/DD/YYYY");

Related

Convert time in react big calendar from 0000000 to 0z

Hi I am currently facing the problem in react where I use react-big-calendar. The time is off by one hour, likely caused because daylight savings and timezone differences.
My code looks like the following:
The part where I struggle is to convert the date in my data object to isoISO 8601. I am unable to parse start and end properties from microsoftgraph Event and any guidance would be appreciated very much!
Note that currently what date I get returned from my event start and end is "2022-11-16T07:30:00.0000000" but I want to convert it to "2022-11-16T07:30:00.0z", if that makes sense.
const data = calendarEvent.map((event: microsoftgraph.Event) => {
return {
id: event.id,
title: event.location.displayName,
allDay: false,
start: new Date(event.start.dateTime),
end: new Date(event.end.dateTime),
}
});
EDIT: Solution was to add a string "z" after event.start.dateTime
It's not the most elegant solution but it works, for now.
Code with the solution implemented:
const data = calendarEvent.map((event: microsoftgraph.Event) => {
return {
id: event.id,
title: event.location.displayName,
allDay: false,
start: new Date(event.start.dateTime + "z"),
end: new Date(event.end.dateTime + "z"),
}
});
The date string is already in ISO-8601 form but has no offset indicator. new Date(string) will parse it assuming it's local to the browser's timezone. On my machine, omitting the offset results in a +02:00 offset:
> new Date('2022-11-16T07:30:00.0000000')
<- Wed Nov 16 2022 07:30:00 GMT+0200 (Eastern European Standard Time)
> new Date('2022-11-16T07:30:00.0000000Z')
<- Wed Nov 16 2022 09:30:00 GMT+0200 (Eastern European Standard Time)
> new Date('2022-11-16T07:30:00.0000000+04:00')
<- Wed Nov 16 2022 05:30:00 GMT+0200 (Eastern European Standard Time)
A dirty hack would be to just append Z to the date string. This will work as long as dateTime has no offset or timezone indicator:
start: new Date(event.start.dateTime + 'Z')
Another option is to use the date library used with react-big-calendar to parse ambiguous date strings as UTC :
start: moment.utc(event.start.dateTime)
event and Timezones
Unfortunately, the dateTimeZone.dateTime field is UTC by default but can refer to a different time zone. This is specified in the dateTimeZone.timeZone field. If there's a chance that MS Graph returns local times, the field property should be checked.
If MS Graph returns an IANA timezone the moment-timezone package can be used to parse both the time and timezone name :
start: moment.utc(event.start.dateTime,event.start.timeZone)
The following call returns 08:30 on my browser's console:
> moment.tz('2022-11-16T07:30:00.0000000','Europe/Vienna').toDate()
<- Wed Nov 16 2022 08:30:00 GMT+0200 (Eastern European Standard Time)

start an event at a specific timezone on react front-end

I'm working on React and I have to do a countdown for an event that start at a precised time at a specific timezone (say 2022/04/20 20:00:00 Paris timezone).
The date is stored in a constant in the front like so :
event:{
start: new Date('2022-04-20T20:00:00'),
end: new Date('2022-04-23T00:00:00')
}
Because the date is stored in front, it will correspond to the user local timezone.
I don't know how to do so that the date stays in paris timezone, whatever the user timezone is.
The date has to stay in a Date type because I do calculations in my Timer for the countdown.
I tried to use formatInTimeZone(date, 'Europe/Paris', 'yyyy-MM-dd HH:mm:ss zzz') from the fns-tz package but when I add the "zzz" at the end it returns an invalid date format.
Also, I noticed that some Dates format are not supported on mobile browsers (the countdown did not display on mobile because of that).
if I changed the date for '2022-04-20T19:00:00Z' would it be the job ?
I know that the Z stands for UTC, but in this case is it UTC+0 ?
I'm really not confortable with the timezones and any help would be appreciated.
I tried :
import { formatInTimeZone } from "date-fns-tz";
const start = new Date("2022-04-20T20:00:00");
const end = new Date("2022-04-23T00:00:00");
const startdate = formatInTimeZone(start,"Europe/Paris","yyyy-MM-dd HH:mm:ss");
const enddate = formatInTimeZone(end,"Europe/Paris","yyyy-MM-dd HH:mm:ss zzz");
export const dropDate = {
start: new Date(startdate),
end: new Date(enddate),
};
It seems to work but not on mobile browser.
The date format is not valid.
If you change the date to '2022-04-20T19:00:00Z', it will just factor in the GMT difference. In my case, My GMT is +0530(IST). So, it will just add 5hrs 30 mins to 19:00:00 which results in 00:30:00 of 21st April.
You can make use of dayjs library instead.
import dayjs from "dayjs";
import utc from "dayjs/plugin/utc";
import relativeTime from "dayjs/plugin/relativeTime";
import timezonePlugin from "dayjs/plugin/timezone";
dayjs.extend(utc);
dayjs.extend(relativeTime);
dayjs.extend(timezonePlugin);
event:{
start: dayjs("2022-04-20T23:30:00").tz('Europe/Paris'),//This will set the start time to 2022/04/20 20:00:00 Paris timezone
end: dayjs("2022-04-23T03:30:00").tz('Europe/Paris') // This will set the end time to 2022/04/23 00:00:00 Paris timezone.
}

How to download data from server using date in get methos React?

I'm new with React. I was looking for information for several days to no avail. So I decided to ask you my stupid question.
I have problem with transforming date from DatePicker to date format which than I can use in get request.
I use DatePicker from this https://www.npmjs.com/package/react-datepicker
Sample correct api call:
localhost:8080/api/measurement/12374?date=2020-12-13 12:00
but date from DatePicker look like:
Sun Dec 13 2020 12:00:00 GMT+0100 (Central European Standard Time)
I play with date for example:
let x = new Date();
let x1 = x.toLocaleDateString() + " " + x.toLocaleTimeString();
output: 23/12/2020 09:29:16
but still I have problem with date format and I also don't know how to pass this date correclty to get method, because http request have % instead "space"
http://localhost:8080/api/measurement/12120?date=23/12/2020%2009:48:15
but when I use string as date it work fine and download data:
let value = "12374";
let date = "2020-12-13 12:00";
const request = "http://localhost:8080/api/measurement/" + value + "?date=" + date;
Can someone explain me how can I convert date from DatePicker to format like this 2020-12-13 12:00 and then use it in get method?
I will be very grateful for any answer!
Thank you ;)
you can use momentjs for this task to format date.
https://www.npmjs.com/package/moment
import moment from 'moment'
let date = new Date();
let result = moment(date).format('DD/MM/YYYY hh:mm')
output: 23/12/2020 02:23

Why isn't date sort working across browsers?

I am trying to implement a date-sorting method for a news list that works across browsers. However, the one method I have tried that works well, only works in Chrome:
origArt.sort(function(a, b) {
var dateA = new Date(a.date), dateB = new Date(b.date);
return dateB - dateA;
});
I also tried this code, suggested in other sorting questions as a possible solution:
origArt.sort(function(a,b){
return (b.date > a.date) ? 1 : (b.date < a.date) ? -1 : 0;
});
But, because the dates in my JSON vary from year; month & year; and month, year and day; the news list sorts in reverse
alphabetical order, not reverse chronological order.
They are strings such as: "2018.", "April 8, 2015.", and "September 2015."
Your problem is that those aren't valid date strings. From some quick testing, Chrome appears to be doing a bit of guesswork as to what you mean, but the other browsers aren't.
Chrome:
new Date("2018.")
// Mon Jan 01 2018 00:00:00 GMT-0800 (Pacific Standard Time)
Firefox:
new Date("2018.")
// Invalid Date
And since Invalid Date > Invalid Date is always false, it isn't sorting anything. It's not just a matter of removing the period either, since "September 2015" also works in Chrome but fails in Firefox.
Ideally, you should fix your JSON or whatever code it's being generated from to use parseable date strings. If that's not an option, you'll probably have to write a custom parsing function that handles all the possible formats you might get, or see if a library like Moment.js can handle it for you.

AngularJS Date Time according to eastern time

I am using AngularJS to get date from service 2014-09-29 and time as 191042 .
I need to show something like this
29 September 2014 19:10:42 ET
How do I convert it according to eastern time zone as I am getting date & time separately?
You can format with a filter {{ date_expression | date : format : timezone}}, in your case: <span>{{datevar | date:'d MMMM y'}} {{timevar | date:'HH:mm:ss' : '-0500'}} ET</span> all the formats you find here: https://docs.angularjs.org/api/ng/filter/date. Check out at this plunker: https://plnkr.co/edit/l7ayOKSPGJp3Uvbfgtlx?p=preview. Completing the answer, if you need to ajust in summer time you can set the local with angular-locale plugin as you can see at this post: Angular JS - Date changes when submitting to $http - Timezone issue

Resources