moment.format() returns next day - fullcalendar

So Im using Fullcalendar and on dayClick I'm trying to find events that match the day clicked.
var events = $calendar.fullCalendar('clientEvents');
if(events.length > 0) {
for (var i = 0; i < events.length; i++) {
if (date.format('YYYY-MM-DD') == events[i].start.format('YYYY-MM-DD')) {
...
Now
date.format('YYYY-MM-DD')
returns the day I clicked but when the for loop gets to that days events then
events[i].start.format('YYYY-MM-DD')
returns the next day. This seems to be affected by UTC but this applies to ALL days with events. Not just today. I've tried different formats and still the same. Here's something I noticed though:
n
_ambigTime:false
_ambigZone:true
_d:Thu Feb 09 2017 08:00:00 GMT-0500 (EST)
_f:"YYYY-MM-DD HH:mm:ss"
_fullCalendar:true
_i:"2017-02-08 13:00:00"
_isAMomentObject:true
_isUTC:true
_isValid:true
_locale:f
Notice that _d and _i are different. _i is actually the right date/time. So how can I reference that?

All moment properties starting with _ (like _d and _i) are for internal use and should not be used.
If you want to check if two moment object represent the same day you can use isSame passing the second parameter to limit granularity, instead of comparing formatted strings. In your case:
date.isSame(events[i].start, 'day')
The problem is that some of your objects are created in UTC mode (_isUTC: true), so they will be displayed using UTC time (previous day in some cases) instead of local time.
More info about UTC mode here:
By default, moment parses and displays in local time.
If you want to parse or display a moment in UTC, you can use moment.utc() instead of moment().
This brings us to an interesting feature of Moment.js. UTC mode.
While in UTC mode, all display methods will display in UTC time instead of local time.

Related

Moment return the same value passed to it instead of utc value

Im trying to trasform a date to utc but moment return the same value i use.
for example
moment(date, 'YYYY-MM-DD HH:mm:ss').utc().format('YYYY-MM-DD HH:mm:ss')
if i use date = '2022-01-07 11:30:00' moment return 2022-01-07 11:30:00
do i have to set the timezone of the value first? why moment return the wrong value? it should return +3 hours that date.
You'll need to define the timezone in which the date is, then the offset will be as expected:
Example, using Europe/Amsterdam as timezone
const date = '2022-01-07 11:30:00';
const utc = moment(date, 'YYYY-MM-DD HH:mm:ss')
.tz('Europe/Amsterdam')
.utc()
.format('YYYY-MM-DD HH:mm:ss');
console.log(utc);
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.1/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment-timezone/0.5.32/moment-timezone-with-data.min.js"></script>
This will output 2022-01-07 10:30:00 since Amsterdam time is -1 compared to UTC.
Small side node, quoting MomentJS Project Status page
We now generally consider Moment to be a legacy project in maintenance mode. It is not dead, but it is indeed done.
In practice, this means:
We will not be adding new features or capabilities.
We will not be changing Moment's API to be immutable.
We will not be addressing tree shaking or bundle size issues.
We will not be making any major changes (no version 3).
We may choose to not fix bugs or behavioral quirks, especially if they are long-standing known issues.
The data you pass in doesn't have any indication of the timezone it's in, so moment is (I believe) assuming it's in utc already.
In related news, look into using the date-fns library instead of moment. Moment is getting old...
Moment github
Moment.js is a legacy project, now in maintenance mode. In most cases,
you should choose a different library.
This returns the same date since you never indicated any timezone
var time = moment("2013-08-26 16:55:00") //this creates time in my tz
You can set a timezone like this:
var time = moment("2013-08-26 16:55:00").tz("America/Los_Angeles");

how can I get a custom timezone datetime from utc timestamp with javascript(node.js)

my backend server stores a utc timestamp with python and send it to frontend.
from datetime import datetime
utcTs = datetime.utcnow().timestamp()
and then frontend app (node.js) get the utcTs , convert it to locale time (or custom timezone)
I code like this:
moment.unix(utcTs).add(8,'hour').format()
because the utcTs is a utc+0 timestamp, how can I initialize a moment object as utc+0, so I can convert it to other timezone easily.
for example, my locale is utc+8.
moment.tz(utcTs,'Asia/Shanghai').format()
return a incorrect time.
is there any gentle way? thanks
The timestamp returned from Python's timestamp() method is in terms of UTC-based seconds from the Unix epoch, so you just need to do the same thing in Moment.
// this is in seconds, but creates a moment in local mode
moment.unix(utcTs).add(8,'hour').format()
// you need to get it in UTC mode with the .utc(). Adding gives a moment 8 hours later.
moment.unix(utcTs).utc().add(8,'hour').format()
// this is how you get it in a fixed offset instead of adding
moment.unix(utcTs).utcOffset('+08:00').format()
Since not all time zones can use fixed offsets, the following is a better approach.
// this is incorrect, as the input would interpreted as milliseconds
moment.tz(utcTs,'Asia/Shanghai').format()
// this is the correct way for it interpreted in terms of seconds
moment.unix(utcTs).tz('Asia/Shanghai').format()

Moment.js internal object what is "_d" vs "_i"

I am using Moment.js and manipulating a date using moment.hour(xx) moment.minute(xx).
When i console.log the moment i see that the object contains a _d and _i:
the _d contains the correct changed moment.hour() or moment.minute() changes however the _i object contains the original?
k {_isAMomentObject: true, _i: Thu Dec 11 2014 20:34:00 GMT+0200 (South Africa Standard Time), _isUTC: false, _pf: Object, _locale: j…}
_d: Thu Dec 11 2014 14:00:00 GMT+0200
_i: Thu Dec 11 2014 20:34:00 GMT+0200
Could anyone enlighten me?
Pay no attention to those. Use the various output functions, such as .format() instead. See the Moment.js guidance on this topic. In short, all fields that are prefixed with an underscore (_) should be considered off limits.
The moment internals have some quirks due to how the Date object works. All of the functions in the public API take them into account, but you probably don't want to figure them out yourself.
Just to be complete though, I'll elaborate on their purpose:
_i is the input used when create the moment object. It can be a string, a number, an array, or a Date object.
However, if another moment object is passed in, the _i will be copied to that moments _i, and other properties will also be copied over. _i will never be a moment object.
_i can also be undefined, in the case of creating the current moment with moment().
_d is the instance of the Date object that backs the moment object.
If you are in "local mode", then _d will have the same local date and time as the moment object exhibits with the public API. The timestamps returned by getTime or valueOf will also match.
If you are in "UTC mode", then _d will still have the same UTC date and time as the moment object exhibits with the public API. This may be confusing, as you'd need to look at getUTCDate and other UTC-based functions on _d in order to see them match. The timestamps will still match here as well.
If you've changed the time zone offset, with the utcOffset, zone, or tz functions, then the _d value cannot stand alone. It must also consider if _offset is defined. If it is, then the timestamp backing the _d object has to first be adjusted by the amount of the offset. You can see this behavior in the implementation of the valueOf method here.
Also, if you look at the string output of _d when a different offset or time zone has been applied, it will appear that _d is using the local time zone. However, that conversion to local time is simply a side effect of the toString function of the Date object. Moment does not use that result in its functions.
This is the behavior for these two fields as of the current version (2.10.6 as I'm writing this). However, there are other fields as well, and since these are internal fields, it's entirely possible the behavior could change in a future version. In particular, see issue #2616.
As a complement to #Matt's answer:
Checkout this result from the chrome's console:
date1 is a moment's valid object:
As you can see, ._d and ._i have different values. So you better use the format() function (as #Matt Johnson wrote) inside your source code.

DateTime changes by Breeze before save changes

I am creating a new Entity and inside constructor I set the datetime like
function Project() {
this.created = moment().format();
}
which produce a result in console the current date and time
Sat Jun 07 2014 18:48:41 GMT+0500 (Pakistan Standard Time)
As soon as I call save changes and see the posted date in the network tabe it changes the hour part of datetime 2014-06-07T13:48:41.000Z
It looks like Breeze does this, may be I am wrong, Any suggestion how can I prevent this to happen?
Breeze is just serializing the date for transport It is not transformed at all. If you look it is 5 hours different in UTC meaning it will localize out the same when you moment.format it again.
If you want to re-localize it just use moment(yourDate).format(LL) or something similar.
http://momentjs.com/ and go to Internationalization section

Flex- Time Zone Conversion

How to convert date and time to CDT time Zone in flex4
Regards,
Sushma
The Date object in Flash is always set to the computer's time settings. If the computer is already in the CDT timezone, then just getting any property from the object will be good. However, if you want to do a timezone 'conversion' into a timezone that the computer is not set to, you can get the UTC time and offset it like this:
var date:Date = new Date();
var timezone:int = -5;
date.hours = date.hoursUTC + timezone;
However, you're trying to get the actual CDT time, which only works during the summer in certain areas. For this, it's impossible for Flash to know exactly when that is UNLESS you code the exceptions (ie. if between this date and that date, do -6, else do -5) and you also need to know the actual location of the user (which is impossible through Flash unless the user gives you that info).
Can I ask why you need to know such a thing?

Resources