I'm seeing some surprising behavior adding a duration to a moment:
var moment = require('moment');
var now = new moment();
var halfday = moment.duration(1/2, 'd');
var fullday = moment.duration(1, 'd');
var day_ago = now.clone().subtract(fullday);
var halfday_ago = now.clone().subtract(halfday);
var otherhalf_ago = now.clone().subtract(halfday.as('ms'));
if (day_ago.isSame(halfday_ago)) { console.log("surprise!"); }
if (!halfday_ago.isSame(otherhalf_ago)) { console.log("surprise!"); }
examining the actual dates, subtracting halfday subtracts a full day (and adding halfday adds nothing). doing the computation with halfday.as('ms') produces the correct result. The momentjs code is pretty opaque in this regard, is this expected behavior?
Related
I have been using the same script to import appointments to Calendar for 2 years with no issues. All of a sudden today, I am getting an error code that reads TypeError: Cannot find function createAllDayEvent in object Calendar. (line 35, file "Code")
Why is this happening?? We use this script to schedule company deliveries, so I really need it to work. Any help would be greatly appreciated!!
This is the script I have been using...
function importCalendar() {
var sheet = SpreadsheetApp.getActiveSheet();
var headerRows = 1; // Number of rows of header info (to skip)
var range = sheet.getDataRange();
var data = range.getValues();
var calId = "CALENDAR ID HERE";
var cal = CalendarApp.getCalendarById(calId);
for (i=0; i<data.length; i++) {
if (i < headerRows) continue; // Skip header row(s)
var row = data[i];
var startDate = row[3]; // Fourth column
var title = row[1]; // Second column
var location = row[2];
var description = row[4];
var id = row[6]; // Seventh column == eventId
var advancedArgs ={description: description, location: location};
// Check if event already exists, update it if it does
try {
var event = cal.getEventSeriesById(id);
}
catch (e) {
// do nothing - we just want to avoid the exception when event doesn't exist
}
if (!event) {
//cal.createEvent(title, new Date("March 3, 2010 08:00:00"), new Date("March 3, 2010 09:00:00"), {description:desc,location:loc});
var newEvent = cal.createAllDayEvent(title, new Date(startDate), advancedArgs).getId(); This is the row with the error.
row[6] = newEvent; // Update the data array with event ID
}
else {
Utilities.sleep(5000);
event.setTitle(title);
event.setDescription(description);
event.setLocation(location);
// event.setTime(tstart, tstop); // cannot setTime on eventSeries.
// ... but we CAN set recurrence!
var recurrence = CalendarApp.newRecurrence().addDailyRule().times(1);
event.setRecurrence(recurrence, new Date(startDate));
}
debugger;
}
// Record all event IDs to spreadsheet
range.setValues(data);
}
You may refer with this thread: Cannot find function createEvent (or createAllDayEvent) in object Calendar. (Google Spreadsheet App). Make sure that yout startDate variable has the right format.
if you are not sure about the 'date' variable being actually a date
you could use
cal.createAllDayEvent(title, new Date(date), {description:desc,location:loc});
that said, it is quite easy to check with the logger
Logger.log(date)
should return a date value in the form Tue Sep 18 03:00:00 PDT 2012
Additional reference: Google script google sheet to calendar TypeError: Cannot find function createEvent in object Calendar. (line 18, file "Code")
How to update momentjs object with other momentjs object without changing reference?
var aObj = moment();
var bObj = moment();
I would like to update all members of aObj with bObj members.
This code is doing what you want
var bObj = moment();
var aObj = moment(bObj);
This code mutates the moment-object, but doesn´t take care about the timezone:
var momentA = moment().tz("Europe/Berlin");
var momentB = moment().tz("America/Los_Angeles").add(2, 'years');
momentA.set(momentB.toObject());
console.log(momentA.tz()); // "Europe/Berlin"
console.log(momentA.format()); // 2019-02-07T14:11:36+01:00
edit:
You could also use Object.assign()
Object.assign(momentA, momentB.clone());
console.log(momentA.tz()); // "America/Los_Angeles"
Can you try this.
var bObj = moment();
var aObj = bObj.clone();
Then you can check with bObj.format("DD-MMM-YYYY HH:ss") and aObj.format("DD-MMM-YYYY HH:ss").
Template.display_time.time = function() {
var date = new Date();
var hour = date.getHours();
var minute = date.getMinutes();
var now = addZero(hour) + ":" + addZero(minute);
return now
};
At the moment im using this code to display the time.
But I've been trying to use simple javascript to update it every second, yet it wont show up on the page.
Is there a meteor friendly way to do this using the function above?
Like using setTimeout on 1 second interval..
The javascript I used to use.
function updateTime() {
var currentTime = new Date();
var hours = currentTime.getHours();
var minutes = currentTime.getMinutes();
if (hours < 10)
{
hours = "0" + hours;
}
if (minutes < 10)
{
minutes = "0" + minutes;
}
var v = hours + ":" + minutes + " ";
setTimeout("updateTime()",1000);
document.getElementById('time').innerHTML=v;
}
updateTime();
The reason that method doesn't work is because it isn't a reactive data source.
Try the following.
Template.display_time.time = function() {
return Session.get('time');
};
Meteor.setInterval(function() {
Session.set('time', getTime());
}, 1000);
See the documentation on Deps
"Meteor has a simple dependency tracking system which allows it to
automatically rerun templates and other computations whenever Session
variables, database queries, and other data sources change."
The algorithm must take in an Int-value of the number of seconds remaining (ex. 2005), then convert and return a "0-padded-String" of the hours, minutes, and seconds remaining (ex. 02:35:15).
I have another event handler that will invoke the above algorithm change in seconds (count down).
Here is an implementation for your conversion method:
public static function Seconds2HHMMSS(Time:Number):String
{
var hours:int =int(int(Time/60)/60);
var hoursZeroPadding:String = "";
if (hours<10)
hoursZeroPadding="0";
var minutes:int =int(Time/60)%60;
var minutesZeroPadding:String = "";
if (minutes<10)
minutesZeroPadding="0";
var seconds:int =Time%60;
var secondsZeroPadding:String = "";
if (seconds<10)
secondsZeroPadding="0";
var result:String = hoursZeroPadding + hours.toString()
+ minutesZeroPadding + minutes.toString()
+ secondsZeroPadding + seconds.toString();
return result;
}
The opposite conversion is quite simpler:
public static function HHMMSS2Seconds(Time:String):int
{
var result:int = int(Time.substr(0,2))*3600
+ int(Time.substr(2,2))*60
+ int(Time.substr(4,2));
return result;
}
Use div and mod and your knowledge of how many seconds in an hour / min / second to come up with each of the groupings. You can then do a padding of zeros with an if statement (or the ?: operator)
Edit: or just use Dunaril's code, I didn't want to just give you the code without you having tried something first, that goes against the spirit of SO for me :P
If I have a tag:
<span class="utctime">2010-01-01 11:30 PM</span>
I would like a jquery script or plug in to convert every utctime class to the current user's browser local time. I would prefer to find this before writing one.
Ok, so I created one that does it:
/*
Note: this requires that the JQuery-DateFormat plugin (available here) be loaded first
http://plugins.jquery.com/project/jquery-dateFormat
*/
(function ($) {
$.fn.localTimeFromUTC = function (format) {
return this.each(function () {
// get time offset from browser
var currentDate = new Date();
var offset = -(currentDate.getTimezoneOffset() / 60);
// get provided date
var tagText = $(this).html();
var givenDate = new Date(tagText);
// apply offset
var hours = givenDate.getHours();
hours += offset;
givenDate.setHours(hours);
// format the date
var localDateString = $.format.date(givenDate, format);
$(this).html(localDateString);
});
};
})(jQuery);
Usage:
<span class="utcdate">2/5/2010 10:30 PM</span>
$('.utcdate').localTimeFromUTC('MM/dd/yyyy hh:mm a');
Use input date to find time zone offset. Important for DST changes.
(function ($) {
$.fn.localTimeFromUTC = function (format) {
return this.each(function () {
// get provided date
var tagText = $(this).html();
var givenDate = new Date(tagText);
if(givenDate == 'NaN') return;
// get time offset from browser
var offset = -(givenDate.getTimezoneOffset() / 60);
// apply offset
var hours = givenDate.getHours();
hours += offset;
givenDate.setHours(hours);
// format the date
var localDateString = $.format.date(givenDate, format);
$(this).html(localDateString);
});
};
})(jQuery);
Use it like....
function ConvertDatesToLocalTime() {
$('.ConvertUtcToLocal').localTimeFromUTC('MM/dd/yyyy hh:mm:ss a');
}
$(document).ready(function () {
ConvertDatesToLocalTime();
});
Assign 'ConvertUtcToLocal' class to all elements requiring conversion.
$(".localdatetime").each(function () {
var datestr = $(this).text();
//alert(datestr);
if (datestr.trim() != '') {
var dateOb = (new Date(Date.parse(datestr, 'MM-dd-yyyy HH:mm'))).setTimezone("GMT").toString('dd MMM yyyy hh:mm tt');
//alert(dateOb);
$(this).text(dateOb);
}
})
this can also be used along with Date.js library to display time in user timezone
CodeGrue thanks so much for sharing this with the community.
For those who are forced to work with other timezones than UTC .. you can alter the function by adding the time difference like this:
Original snippet:
var offset = -(currentDate.getTimezoneOffset() / 60);
Snippet altered to work with CEST timezone (Time zone offset: UTC + 2 hours):
var offset = -(currentDate.getTimezoneOffset() / 60 + 2);
and so on.
When I used this, I had to change the line
var hours = givenDate.getHours();
to
var hours = givenDate.getUTCHours();
When debugging through this, the line var givenDate = new Date(tagText) ends up creating a Date object that is in UTC (if you give it a date in RFC1123 format, e.g. ddd, dd MMM yyyy HH:mm:ss GMT), but when you call getHours on that you get the hours in the local time zone. So unless you call getUTCHours, it doesn't work.
So the full thing is
/*
Note: this requires that the JQuery-DateFormat plugin be loaded first
http://plugins.jquery.com/project/jquery-dateFormat
*/
(function ($) {
$.fn.localTimeFromUTC = function (format) {
return this.each(function () {
// get time offset from browser
var currentDate = new Date();
var offset = -(currentDate.getTimezoneOffset() / 60);
// get provided date
var tagText = $(this).html();
var givenDate = new Date(tagText);
// apply offset
var hours = givenDate.getUTCHours();
hours += offset;
givenDate.setHours(hours);
// format the date
var localDateString = $.format.date(givenDate, format);
$(this).html(localDateString);
});
};
})(jQuery);
See this other question for how I used it in combination with the timeago plugin.