How to set local timezone in Sails.js or Express.js - datetime

When I create or update record on sails it write this at updateAt:
updatedAt: 2014-07-06T15:00:00.000Z
but I'm in GMT+2 hours (in this season) and update are performed at 16:00.
I have the same problem with all datetime fields declared in my models.
How can I set the right timezone on Sails (or eventually Express) ?

The way I handled the problem after hours of research :
Put
process.env.TZ = 'UTC'; //whatever timezone you want
in config/bootstrap.js

I solved the problem, you should setting the MySql options file to change timezone to UTC
in the config/connections.js
setting at this
devMysqlServer: {
adapter: 'sails-mysql',
host: '127.0.0.1',
user: 'root',
password: '***',
database: '**',
timezone: 'utc'
},

Trying to solve your problem by setting the timezone on your server is a bit short-sighted. What if you move? Or someone in a different country accesses your application? The important thing is that the timestamps in your database have a timezone encoded in them, so that you can translate to the correct time on the front end. That is, if you do:
new Date('2014-07-06T15:00:00.000Z')
in your browser console, you should see it display the correct date and time for wherever you are. Sails automatically encodes this timestamp for you with the default updatedAt and createdAt fields; just make sure you always use a timezone when saving any custom timestamps to the database, and you should be fine!

The best architecture planning here, IMO, is to continue using Sails.js isoDate formatting. When you're user's load your website/app the isoDate will be converted to their client/browser timezone which is usually set at the OS level.
Here's an example you can test this out with. Open a browser console and run new Date().toISOString() and look at the time it sets. It's going to be based of off the spec for isoDate 8601 (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString).
Now, change your system time to a different time zone or simply change your hour on the time and save (you shouldn't have to reload if you're using chrome console). Run your command in the console again new Date().toISOString() and you'll get an adjusted time appropriate to the time you just changed.
If you'd like to continue on proving to yourself the time Sails.js is appropriate to use, use Moment.js on an isoDate that is stored in your database (created by waterline ORM) like so moment("2016-02-05T22:36:48.800Z").fromNow() and you'll notice the time is relative to your system time.

I've come to grips with not setting a timezone at the app level (I see why the sails authors did it that way), however I've been having a rough time performing a simple date match query. I'd assume that if you create a record using the default blueprint methods (this one containing an extra datetime field over the defaults), passing in a date, that you'd be able to pass in the same date in a get query and get the same record.
For example, let's say the datetime field is called "specialdate". If I create a new record through the api with "specialdate" equaling "06-09-2014" (ignoring time), I haven't been able to run a find query in which I can pass in "06-09-2014" and get that record back. Greater than queries work fine (if I do a find for a date greater than that). I'm sure it's a timezone offset thing, but haven't been able to come up with a solution.

Related

Get Firestore Server Timestamp from the client side

I'm building an app that tracks time. It calculates the time by differentiating the seconds like so:
serverTimestamp: FieldValue // {seconds: number, milliseconds: number}.
getSeconds() {
const createdTime = new Date(this.serverTimestamp * 1000).getTime()
const currentTime = new Date().getTime();
return Math.abs((currentTime - createdTime) / 1000);
}
The problem is that Date's values equal to the current client's device clock, while firestore's timestamp equal to the firestore server, which may cause inequivalence between these two dates.
The leads me with two alternatives:
1. Save Date instead of serverTimestamp().
This way, the difference between these two dates will be accurate. Although, they won't represent the real date. Plus, if the user will change his clock on his machine, then the seconds would be changed too.
2. Create an HTTPS function that retrieves the current server timestamp.
This way, the difference between these two dates will be accurate either. Although, it feels like I'm going too far only to get the current timestamp of the server.
I am probably going to stick with alternative number two. But I was hoping if there's a better solution to achieve my goal.
PS - I'm using #angular/fire. So, solutions from this package would be welcomed.
You can also write the current timestamp with a serverTimestamp, then read the time back out of the location it was just written. Then you can make changes or calculations with that value.

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

events (as a json feed), start end parameters unix timestamp, are different if I change my OS time zone

I'm using the fullcalendar plugin and would appreciate if someone can give me a hand.
I am getting json events through a PHP URL.
something like this:
$('#calendar').fullCalendar({ events: "/myfeed.php" });
So in my php page that returns the events, I am getting 3 GET parameters:
'_'
'start'
'end'
The start and end parameter, indicate the date in UNIX timestamp.
So far so good, the problem that occurs is that if I change the time zone on my OS. also change these parameters start and end, for the same query in the same day in the calendar.
the weirdest part is that it only happens in Mozilla Firefox.
in Google Chrome, this problem does not occur.
e.g.
I have set my time zone ((UTC-04: 00) Santiago)
I'm referring to the day 09.09.2012 on the agenda,
firebug shows me that these parameters are being sent to my php page
_ 1347245953581
end 1347246000
start 1347159600
but if I change the time zone from my OS to ((UTC-03: 00) Buenos Aires)
consulting on 09.09.2012 on the agenda,
are other parameters which are now sent to the PHP page.
_ 1347246338047
end 1347332400
start 1347246000
Being that it is the same day, are other start and end parameters which are sent to check for events.
There is an ignoreTimezone option on the fullcalendar that might help. I'm not sure if it affects the start/end time passed to the feeds.
http://arshaw.com/fullcalendar/docs/event_data/ignoreTimezone/
Another option is to convert the passed timestamp to a Date object and get the local data from the Date object afterwards and use that in your queries.
Convert a Unix timestamp to time in JavaScript
I know it is not the exact answer, but it might help you out a bit.
Here is a sample piece of PHP code to convert the passed timestamp into a local formatted date:
$startts = $_REQUEST["start"]; // original timestamp
$startdt = new DateTime('now', new DateTimeZone('Europe/Oslo') ); // setup a local datetime
$startdt->setTimestamp($startts); // Set the date based on timestamp
echo $startdt->format('Y-m-d H:i:s'); // Output local date and time

How to get different country time into single page using flex or flash (action script 3) because getTime() used for get current time only

i am beginner dont know how do display all country time into a single page using action script 3 in flex . do u know any example time code refer me . i will try that code .
In Actionscript/Flex, you can only get either the local time, which is from the user's operating system, or the UTC time. You'll have to find a way of converting UTC to the user's time - or use externalInterface to communicate with something like java.
In Java you can use Calendar.getInstance(TimeZone zone) method to create a Calendar object of a timezone. TimeZone.getAvailableIDs() will give you list of inbuild timezones supported by Java. You can find out the timezones you want and using the id can create the TimeZone object from TimeZone.getTimeZone(String ID)

Resources