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

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");

Related

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()

System.DateTime comparison ('>') or ('<') does not give what I expected

I want to get files from a list for all the files whose filedate > today's cutOff - so, I have the following codelet
string[] MyFiles = Directory.GetFiles(MyConfig.pathTransmittedFiles, "*.adf")
.Where(file => new FileInfo(file).LastWriteTime > dtCutOff).ToArray();
I have a file whose LastWriteTime is "{11/3/2015 1:33:26 PM}" being picked up by my collection with dtCutOff == "{11/3/2015 1:33:26 PM}"! So '>' didn't seem to work.
First, I would try running it without the Where clause, just to make sure that all files you expect are indeed part of the initial array returned from Directory.GetFiles. It's entirely possible that date/time comparison is not the source of the discrepancy. It may be more related to the issue Ivan linked to in the question comments, or it may be permission related, or some other thing.
Next, be aware that DateTime violates SRP in that it has a Kind property, which is one of the three DateTimeKind enumeration values. It's either Local, Utc, or Unspecified.
In the case of DateTime.Now, the Kind will be DateTimeKind.Local. File.GetLastWriteTime also returns its value with local kind. Therfore, if you always derive your dtCutOff from DateTime.Now in the manner you showed in the question, then it will almost always be the correct comparison function.
The "almost" stems from the fact that DateTimeKind.Local can actually represent two different kinds under the covers. In other words, there are actually four kinds, but two of them are exposed by one. This is described as "DateTime's Deep Dark Secret" in Jon Skeet's blog post More Fun with DateTime, and is also mentioned in the comments in the .NET Framework Reference Source. In practice, you should only encounter this in the ambiguous hour during a fall-back daylight saving time transition (such as just occurred last Sunday 2015-11-01 in the US).
Now, to the more likely case that your dtCutOff is actually derived not from DateTime.Now, but rather from user input or database lookup or some other mechanism, then its possible that it actually represents the local time in some other time zone than the one on your local computer. In other words, if the dtCutOff has a Kind of DateTimeKind.Utc, then the value is in terms of UTC. If it has a Kind of DateTimeKind.Unspecified, then the value might be in terms of UTC, or the local time zone, or some other time zone entirely.
Here's the kicker: Comparison of two DateTime values only evaluates the value underlying the Ticks property. It does not consider Kind.
Since file times are absolute points in universal time (on NTFS anyway), then you really should use the File.GetLastWriteTimeUtc method, rather than the methods that work in local time.
There are two approaches you could use:
Load the modified property as UTC, using:
myResult.modified = File.GetLastWriteTimeUtc(myFile);
Populate dtOffset appropriately.
If you're loading from the current time, then use DateTime.UtcNow.
If you're loading from other input, ensure the value is converted to UTC to match the input scenario. For example, use .ToUniversalTime() if the value is in terms of the local time zone, or use the conversion functions in the TimeZoneInfo class if the value is in another time zone.
OR
Change your modified property to be a DateTimeOffset instead of a DateTime.
Load that using:
myResult.modified = new DateTimeOffset(File.GetLastWriteTimeUtc(myFile));
Define dtCutOff as a DateTimeOffset, and populate appropriately.
If you're loading from the current time, then use DateTimeOffset.UtcNow.
If you're loading from other input, ensure the offset is set to match the input scenario. Use TimeZoneInfo functions if you need to convert from another time zone.
DateTimeOffset has many advantages over DateTime, such as not violating SRP. It's always representing an absolute moment in time. In this scenario, it helps to know that comparison operators on DateTimeOffset always reflect that absolute moment. (In other words, it internally adjusts to UTC before doing the comparison.)
This code works:
var cutffDate = new DateTime(2015,1,1); // or whatever
var allFiles = Directory.GetFiles(MyConfig.pathTransmittedFiles, "*.adf");
var datedFiles = allFiles.Where(f => (new FileInfo(f)).LastWriteTime > cutffDate);
Update:
Since your issue seems to be a precision-related one you could change the comparison to:
const long precision = 10; // vary this as needed
allFiles.Where(f =>
(new FileInfo(f)).LastWriteTime.ToFileTime()/precision > cutffDate.ToFileTime()/precision);
Alternatively you could use ...LastAccessTime.Ticks/TimeSpan.TicksPerMillisecond
In addition to that you may need to convert all DateTime values to UTC (LastAccessTimeUtc and DateTime.UtcNow) to make sure it's not some weird timezone issue
Since the files were fed into the queue once a day so the scale of precision is not required down to a millisecond or something. So that one-second TimeSpan difference is acceptable to do the trick and make my case work.
string[] MyFiles = Directory.GetFiles(MyConfig.pathTransmittedFiles, "*.adf")
.Where(file => new FileInfo(file).LastWriteTime - TimeSpan.FromSeconds(1) > dtCutOff)
.ToArray();
Now my file with modified date "{11/3/2015 1:33:26 PM}" didn't go into my collection when my cutOffDate is "{11/3/2015 1:33:26 PM}" while my other file with modified date "{11/3/2015 1:33:27 PM}" have successfully passed into my collection as expected!! So, it works and that's how it should work after all these advises! Thanks ye-all.
Looks like your Where clause lambda might be incorrect. Try this.
string[] MyFiles = Directory.GetFiles(MyConfig.pathTransmittedFiles, "*.adf").Where(file => file.modified > dtCutOff).ToArray();

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.

How do I let moment know the date that I'm giving it is in UTC?

Apologies in advance. Due to the popularity of this library I'm sure the answer is out there but I haven't been able to find it.
I'm getting timestamps back from an api in this format
2014-09-27T00:00:00-07:00
where this part is in UTC
2014-09-27T00:00:00
and this part is the timezone offset
-07:00
When converting to a moment I can't figure out how to let moment.js know that the time I'm passing it is in UTC.
If I try this
var time = moment('2014-09-27T00:00:00-07:00');
console.log(time.format("YYYY-MM-DDTHH:mm:ss"));
time.local();
console.log(time.format("YYYY-MM-DDTHH:mm:ss"));
both console logs output the same
however if I do this
var time = moment('2014-09-27T00:00:00-07:00');
time.utc();
console.log(time.format("YYYY-MM-DDTHH:mm:ss"));
time.local();
console.log(time.format("YYYY-MM-DDTHH:mm:ss"));
It will accurately add 7 hours (my time difference from UTC) log it, remove the time again and log it again.
I've tried
var time = moment.utc('2014-09-27T00:00:00-07:00');
but even then the .local() method doesn't do anything.
What am I missing?
An additional related question... In standard ISO 8601 format is the time string understood to be local time or UTC? With the offset one could convert in either direction, I'm just not sure what the starting point is.

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