How to shift fullcalendar's display time by several minutes - javascript

This could be an embarrassingly easy question but I am new to Moment.js and fullcalendar.
The goal: Get fullcalendar to operate on a Moment/DateTime that is a few minutes offset from local computer time.
The rationale:
We want to synchronize the display time and nowIndicator with the old clocks in a building as opposed to the desktop's time.
Tried so far:
// Get current offset:
var localOffset = moment().utcOffset();
// Shift by 7 minutes for illustration
localOffset -= 7;
// Set new offset for moment
moment().utcOffset(localOffset);
alert(moment().utcOffset());
As of now it prints back the original UTC offset and the nowIndicator matches my system clock. This is using Moment.js 2.19.0.
Thanks for looking.

moment().utcOffset() is creating a new moment with the default offset. It has nothing to do with the object you previously set an offset on. momentJS works using individual objects which are instantiated by using the moment() constructor. It's not a static or global thing.
What you need to do is work with the moment object which you set the offset on:
var offsetMoment = moment();
offsetMoment.utcOffset(localOffset);
alert(offsetMoment.utcOffset());

ADyson's answer cleared the misconception about a moment object and its scope.
To answer the original problem of shifting FullCalendar's time by an arbitrary amount, use the 'now' option when initializing:
// Get current time as moment object and add 7 minute offset
var shiftedTime = moment().add(7, 'minutes');
// Set 'now' option in calendar initialization to new moment object
$('#calendar').fullCalendar({
// put your options and callbacks here
now: shiftedTime,
defaultView: 'agendaDay',
nowIndicator: true
});
The display of the calendar and the now indicator will be shifted 7 minutes relative to local machine time.

Related

How to convert any timezone to local timezone in javascript?

The below code converts the date to local timezone:
function convertDateToServerDate(incomingDate) {
var serverOffset = new Date();
serverOffset = serverOffset.getTimezoneOffset();
var outgoingServerDate = new Date((incomingDate.getTime() + Math.abs(serverOffset * 60 * 1000)));
return outgoingServerDate;
}
I have a date in the IST timezone. I'm also in the IST timezone the above function changes the time whereas it should just return it. I also tried converting to UTC then back to the local but the same result. How to get a local timezone and do nothing if the date is already in local time zone?
You can't do this with vanilla Javascript without a library, because the Date class only comprehends two timezones: GMT, and local. (Source]
Libraries like momentjs and date-fns do not merely provide convenient functions, they very importantly also include hard-coded datasets that specify current real-world facts about time zone adjustments, including things like the dates where DST switches. This is vital, because if you look at the map of timezones, you'll see that the boundaries of the different zones are not straight lines. That's because they are determined by humans who made interesting compromises which are then enshrined in custom and law.
Many of those compromises are there so that people who share a jurisdiction can also share a clock. It would be enormously inconvenient for them otherwise, and many people would be adversely impacted every single day.
There is a proposal for a successor to Date, called Temporal, that would remedy this.
Best to use moment library. https://momentjs.com/timezone/docs/
moment().tz(String)
var a = moment.utc("2013-11-18 11:55").tz("Asia/Taipei");
var b = moment.utc("2013-11-18 11:55").tz("America/Toronto");
a.format(); // 2013-11-18T19:55:00+08:00
b.format(); // 2013-11-18T06:55:00-05:00
a.utc().format(); // 2013-11-18T11:55Z
b.utc().format(); // 2013-11-18T11:55Z
The server offset has to be set using INTL, hardcoded or come from the server
So something like this
const serverOffset = -240; // this is static
function convertDateToServerDate(incomingDate) {
const incomingOffset = incomingDate.getTimezoneOffset();
if (serverOffset === incomingOffset) return incomingDate;
console.log(serverOffset-incomingOffset,"difference")
const outGoingDate = new Date(incomingDate.getTime())
outGoingDate.setTime(incomingDate.getTime() + ((serverOffset-incomingOffset) * 60 * 1000));
return outGoingDate;
}
console.log(convertDateToServerDate(new Date()))

Guesstimate time zone from time offset with JavaScript and Moment.js

I know this is not going to be foolproof because an offset isn't specific to a timezone, but with location data it seems like it would be possible to make an educated guess.
Basically, I would like to be able to take an object similar to this:
{
offset: -5,
location: 'America'
}
...and get back either a single or multiple matching time zones, which would be:
['America/Montreal', 'America/New_York', ...]
One solution I can think of is iterating through the zone data provided by moment-timezone, but that just doesn't seem like an elegant way to get this info.
Any ideas?
It's not really elegant but iterating through the time zone database allows to get all timezones associated with a given offset.
Note that the timezone database stores the variation of offset due to the daylight saving rules and also the historical evolution of time zones.
Given an offset in minutes, this function returns, according to the iana timezone database, the list of all timezones that used this offset once in the history or that will use this offset once in the futur.
function getZonesByOffset(offset){
//offset in minutes
results = [];
var tzNames = moment.tz.names();
for(var i in tzNames){
var zone = moment.tz.zone(tzNames[i]);
for(var j in zone.offsets){
if(zone.offsets[j] === offset){
//Add the new timezone only if not already present
var inside = false;
for(var k in results){
if(results[k] === tzNames[i]){
inside = true;
}
}
if(!inside){
results.push(tzNames[i]);
}
}
}
}
moment-timezone#0.5.0 added moment.tz.guess() which attempts to guess the user's most likely timezone by looking at Date#getTimezoneOffset and Date#toString. It then picks the zone with the largest population. It's not perfect, but it's close enough! Data is pulled from this table and Intl is used when available.
Fiddle
moment.tz.guess()
//= America/New_York (I'm in America/Montreal, but this works too)

jQuery Countdown - Daily Countdown, with secondary countdown as well?

1. Daily Countdown
I'm trying to use Keith Wood's jQuery countdown plugin (http://keith-wood.name/countdownRef.html) in order to create a page of daily countdowns. E.g.:
A - counts down to 07:00 each day
B - counts down to 09:00 each day
C - counts down to 11:00 each day
I'm doing in a fairly hacky way:
var foo = new Date();
foo.setHours(11)
foo.setMinutes(0)
foo.setSeconds(0)
$('#fooCountdown').countdown({until: foo});
Basically, I just create a new Date object which defaults to now, then set the time to the time I want for today.
However, this is pretty hacky, and also it doesn't reset at the end of the day - once the new day ticks over, it's still counting down to the time on the previous day.
Is there a cleaner or better way of doing daily countdowns with this plugin?
2. Secondary Countdown
Secondly - I also want each countdown, when it expires, to count down to a second later time that day.
E.g. for A - once it reaches 07:00, it then starts counting down to 15:00 for that day.
I'm doing this using the onExpiry function:
$('#officeCountdown').countdown({until: officeOpens, onExpiry: OfficeOpen, alwaysExpire: true});
...
function OfficeOpen() {
$('#officeCountdown').countdown('option', {until: officeCloses, onExpiry: OfficeClose, alwaysExpire: true});
}
function OfficeClose() {
alert('Office has closed')
}
The first part - counting down down until officeOpen seems to work.
However, the second part - counting down until OfficeClose doesn't - it seems to always start counting down the difference between officeOpens and officeCloses, instead of using the current time - and also, the function OfficeCLose never seems to trigger.
Any thoughts?
I would suggest you use the excellent Datejs plugin for creating/handling dates.
(read the getting-started and the docs because it is really extensive)
This way you could do
$('#fooCountdownA').countdown({
until: Date.today.set({hour:7})
});
$('#fooCountdownB').countdown({
until: Date.today.set({hour:9})
});
$('#fooCountdownC').countdown({
until: Date.today.set({hour:11})
});
As for the countdown, the plugin does not seem to be friendly to re-using countdowns..
Perhaps you are better off creating dummy elements and inserting them in the dom to hold the countdown, and destroying them on expiry..

Javascript countdown and timezone and daylight saving time issues

Our team are having big issues with the JQuery countdown and we really need some help.
Initially, we had some ScriptSharp code that does this
JQueryCountdownOptions opts = new JQueryCountdownOptions();
opts.Layout = "<ul class=\"group\"> <li>{dn} <span>{dl}</span></li> <li>{hn} <span>{hl}</span></li> <li>{mn} <span>{ml}</span></li> <li>{sn} <span>{sl}</span></li> </ul>";
opts.Until = Number.ParseInt(timeLeft);
jQuery.Select("#countdownclock").Plugin<JQueryCountdown>().Countdown(opts);
jQuery.Select("#countdownclock").Show();
jQuery.Select("#bidBox").RemoveAttr("disabled");
What we noticed is that this uses the client's clock to countdown from. So, if the client decided to change his time to 5 hours ahead then the countdown would be 5 hours off.
To fix this we introduced some more code
In the view:
$(function () {
var expires = new Date(#year, #month, #day, #hours, #minutes, #seconds);
$('#clockDiv').countdown({ until: expires, timeZone: null, serverSync: serverTime, onTick: serverTime, tickInterval: 60 });
function serverTime() {
var time = null;
$.ajax({ url: '/Auction/SyncServerTime',
async: false, dataType: 'json',
success: function (result) {
time = new Date(result.serverTime);
}, error: function (http, message, exc) {
time = new Date();
}
});
return time;
}
});
In the controller
public JsonResult SyncServerTime()
{
var result = new JsonResult
{
Data = new
{
serverTime = DateTime.Now.ToString("MMM dd, yyyy HH:mm:ss zz")
},
JsonRequestBehavior = JsonRequestBehavior.AllowGet
};
return result;
}
This code ensures that no matter what the user sets his clock to the countdown timer will periodically sync to the server's time. Problem solved.
The only issue is that we have come up with other issues.
The problem is that when users are in different timezones then the countdowns of those users are different depending on the timezone offset that their timezone has. We have tried changing all sorts of parameters and still are having issues. To make matters worse if my timespan straddles a date when daylight saving time is applied then things go awry again, both for those in the same timezone and those in different ones. We have experimented with different code and parameters so the above is just what I did and is different from what my esteemed colleagues tried. What I am asking is surely, someone somewhere out there must have had a requirement to
Write a countdown that is independent of client time and based on server time.
Shows the same number of days, hours, minutes, seconds remaining no matter what timezone a user is in
Shows the same number of days, hours, minutes, seconds remaining for a user whose time will change in this period because of DST to user whose time will not change in this period because of DST
Shows the actual number of days, hours, minutes and seconds remaining for a user whose time will change in this period because of DST.
We cannot be the only people who have ever had this issue, surely. It cannot be this hard. Does anyone know a solution?
Thanks,
Sachin
I haven't dealt with the same scenarios personally, but seeing Date, timezone issues etc. pop up automatically triggers thoughts about some potential issues stemming from the use of local date objects as opposed to UTC date objects.
IMO, things are simply better off if all computation, serialization of dates only worked in the UTC space, and finally when it comes to present a date from a user, it is converted to local or appropriate time zone depending on the scenario. On the flip-side, the user enters local or some time zone relative entry, and immediately that is converted to UTC as the internal representation. This avoids all sorts of confusion across different layers/tiers of the app.
Its not really a solution to your specific problem, but perhaps something to consider that could lead to one.

Javascript countdown - not counting down

I have a countdown script that gets the live time and subtracts it from a set time. It all works apart from the fact that it doesn't update unless you refresh your page. The setInterval at the bottom of my function instructs the function to run every one second, but it doesn't seem to be doing that...
Can anybody help?
Here is my jsfiddle: http://jsfiddle.net/4yMZy/
Each time cCountDown runs, its is calculating the time left like so:
nDates = new Date(datetime);
xDay = new Date("Fri, 26 May 2012 16:34:00 +0000");
timeLeft = (xDay - nDates);
The value of datetime there never changes from one run to another. So cCountDown is constantly running, but is always comparing the difference between the same two dates. Since the same two dates are used, the difference is always the same, so you do not see any countdown occur.
You could change nDates = new Date(datetime); to nDates = new Date(); and it will start counting down, but I am not sure why you are getting datetime from some server in the first place.
There are some other issues with your code as well. You should run it through jslint or jshint.
If changed your code to http://jsfiddle.net/4yMZy/7/
So it fetches the time and updates the seconds according to the set interval.
Edit:
jsfiddle actually provides a button for that on the top.

Categories

Resources