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

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

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

adding current time to ambiguous date using momentjs

I'm currently using FullCalendar and need to add the current time to an ambiguous date moment in the select callback function.
When selecting a day in month view, the callback function parameters "start" and "end" return an ambiguous date (no time) moment. I'm using the following to add the current time to the date then convert it back to a moment but wonder if this is the proper way to do it...
if(!start.hasTime()){
start = moment(start.format('YYYY-MM-DD'+' '+ moment().format('HH:mm:ss')));
end = moment( end.format('YYYY-MM-DD'+' '+ moment().format('HH:mm:ss')));
}
As you can see, I'm converting the "start" and "end" dates and current time moments into strings then converting the concatenated string back into a moment.
I want to make sure that the moment i'm creating is in valid ISO 8601 format.
Thanks,
Any help would be appreciated.
In the official docs says if you call format() function you get the date in ISO 8601 format.
check this out: jsfiddle
Furthermore, if you dont want to handle the timezones, you can use the utc() method
I had the same issue, strangely when I upgraded to fullcalendar v3.40. According to fullcalendar docs,
the format() and toISOString functions have been overridden within fullcalendar for ambiguously timed moments to return dates only i.e. '2017-03-06'. To overcome this and set a time, you need to create a new moment object which is what you have done. To ensure consistent parsing across browsers though, you should specify the format you are parsing as recommended by moment docs. So for your scenario, it will be:
if(!start.hasTime()){
var format = 'YYYY-MM-DD HH:mm:ss';
start = moment(start.format('YYYY-MM-DD'+' '+ moment().format('HH:mm:ss')), format);
end = moment( end.format('YYYY-MM-DD'+' '+ moment().format('HH:mm:ss')), format);
}
To make the code cleaner and easily readable though, you could create a new moment using the unix timestamp (which is a number and doesn't rely on string formats) of the start moment and set the time using the moment set function. So it could now look like this:
if(!start.hasTime()){
var timestamp = start.valueOf();
var now = moment();
var startMomentWithNowTime = moment(timestamp).set({
'hour': now.hour(),
'minute': now.minute(),
'second': now.second()
});
start = startMomentWithNowTime;
end = startMomentWithNowTime;
}
Excuse the descriptive variable naming startMomentWithNowTime. A few more lines but hopefully easier to read. You could also wrap this logic in a function to use on demand. Hope it helps!

Google Calendar API v3 time zone issues

Using .Net API wrapper for Google Calendar API.
First get primary calendar id
Get timezone of primary calendar (returns good data, e.g., "America/Los_Angeles")
Create a calendar event. Set start time and end time. Set timezone.
Dim eStart As New EventDateTime
eStart.DateTime = _startAt
eStart.TimeZone = GoogleTimeZone
Dim eEnd As New EventDateTime
eEnd.DateTime = _endAt
entry.Start = eStart
entry.End = eEnd
eEnd.TimeZone = GoogleTimeZone
CalService.Events.Insert(entry, calendarid).Execute()
But the events are being created at 3am when the start time specified is 11am.
Google API documentation states "A time zone offset is required unless a time zone is explicitly specified in timeZone" and for timezone "The time zone in which the time is specified. (Formatted as an IANA Time Zone Database name, e.g. "Europe/Zurich".)".
Timezone value is being specified properly.
Basically, it is not making any difference whether or not timezone is specified. Event is created in GMT in google calendar.
What is wrong here?
Fixed it (or let's just say hacked it). Google .Net API wrappers are absolutely crap (and this goes to wrapper of all of their APIs and not just Calendar API).
The issue was that event.Start and event.End automatically converts dates and add a "Z" at the end. This tells Google that the date is in GMT format. There is no reason for putting a "Z" because even without it, Google considers GMT. So basically, event.TimeZone=value was being disregarded because the time was appended by "Z".
After I removed the "Z", everything worked ok.
entry.Start.DateTimeRaw = replace(entry.Start.DateTimeRaw,"Z","")
entry.End.DateTimeRaw = replace(entry.End.DateTimeRaw,"Z","")
I fixed it by creating an instance of a DateTime object that uses the DateTimeKind enum as one of the constructors. I found the default DateTime.Kind property value is DateTimeKind.Utc when deserializing a JSON date. That's why a Z (UTC) value is in the Raw for me. The time zone value will be correct when DateTimeKind.Local is applied to the DateTimeKind argument in one of the constructors that takes it.
DateTime dt = new DateTime(oldDateTime.Ticks, DateTimeKind.Local);
DateTime dt = new DateTime(yearVar, monthVar, dayVar, hourVar, minuteVar, secondVar, DateTimeKind.Local);
Instead of setting the Datetime property that is part of the Start and End objects, you should give the DateTimeRaw a value and assign a timezone to it like this:
eventItem.Start = new EventDateTime()
{
DateTimeRaw = input.Start.ToString("yyyy-MM-ddTHH:mm:ss"),
TimeZone = "America/New_York"
};
Noticed that I'm not adding a Z or any timezone representation at the end of the string format. That should fix the issue and should prevent google from ignoring the timezone property when you've set a value.
In addition, if you hover over the DateTime property of the Start or End object in Visual Studio, it is described as the following: DateTime representation of EventDateTime.DateTimeRaw(see image).
Which in this case, replacing the Z value for an empty string will only make the problem worst because your DateTime property will also be updated. I hope this is helpful to anyone in the future.

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.

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

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.

Resources