OADate to Milliseconds timestamp in Javascript - javascript

I try to do the exact opposite of :
What is equivalent of DateTime.ToOADate() in javascript?
Create a millisecond date (number of milliseconds since 1/1/1970) from a OADate (number of days since 30 dec 1899 as a double value)
my guess is I can do like this :
this.unixTimeStampFromOADate = function( OADateFloat)
{
var oaDateFor1970 = ?? ; //what's the value for 1/1/1970 in OADate format ?
var delta = Math.floor(OADateFloat - oaDateFor1970);
return delta*(1000*60*60*24);
}
so if I'm right, I need the value for 1/1/1970 in OADate format.
if I'm wrong, please can you suggest another conversion method ?

Javascript dates use a time value that is milliseconds since 1970-01-01T00:00:00Z. The time value for the date 1899-12-30 is -2209197600000.
To get the days since then, get the milliseconds for midnight at the start of today, subtract it from the OA epoch, divide by the ms in one day and get the absolute value. Note that the time values are all UTC so daylight saving, leap years, etc. are accounted for.
var epoch = new Date(1899, 11, 30); // 1899-12-30T00:00:00
var now = new Date(); // 2013-03-22T<current time>
now.setHours(0,0,0,0) // 2013-03-22T00:00:00
var oaDate = Math.abs((epoch - now) / 8.64e7); // 41355 for 2013-03-22
You can test it against some dates here (note that those dates are in the confusing US m/d/yy format).
Edit
Sorry, got the sense backwards. Here are some functions to go both ways.
Also took some time to work out that where it says "OLE Automation date is implemented as a floating-point number whose integral component is the number of days before or after midnight, 30 December 1899" actually means on or after 1899-12-30 00:00:00 and that the "fractional component represents the time on that day divided by 24". In other words, while 1899-12-29 00:00:00 is -1, the value for `899-12-29 06:00:00 is -1.25, not -0.75.
Anyhow, these functions seem to work now, but please test thoroughly:
var toOADate = (function () {
var epoch = new Date(1899,11,30);
var msPerDay = 8.64e7;
return function(d) {
var v = -1 * (epoch - d)/msPerDay;
// Deal with dates prior to 1899-12-30 00:00:00
var dec = v - Math.floor(v);
if (v < 0 && dec) {
v = Math.floor(v) - dec;
}
return v;
}
}());
var fromOADate = (function() {
var epoch = new Date(1899,11,30);
var msPerDay = 8.64e7;
return function(n) {
// Deal with -ve values
var dec = n - Math.floor(n);
if (n < 0 && dec) {
n = Math.floor(n) - dec;
}
return new Date(n*msPerDay + +epoch);
}
}());
var now = new Date();
var oaNow = toOADate(now);
var now2 = fromOADate(oaNow);
alert('Today: ' + now + '\nOADate: ' + oaNow + '\noaNow to Date: ' + now2);
The specification for OADate is confusing, particularly the way negative numbers are handled.
Edit Feb 2019
Updated version of functions, use local date values.
/* Convert a Microsoft OADate to ECMAScript Date
** Treat all values as local.
** #param {string|number} oaDate - OADate value
** #returns {Date}
*/
function dateFromOADate (oaDate) {
// Treat integer part is whole days
var days = parseInt(oaDate);
// Treat decimal part as part of 24hr day, always +ve
var ms = Math.abs((oaDate - days) * 8.64e7);
// Add days and add ms
return new Date(1899, 11, 30 + days, 0, 0, 0, ms);
}
/* Convert an ECMAScript Date to a Microsoft OADate
** Treat all dates as local.
** #param {Date} date - Date to convert
** #returns {Date}
*/
function dateToOADate (date) {
var temp = new Date(date);
// Set temp to start of day and get whole days between dates,
var days = Math.round((temp.setHours(0,0,0,0) - new Date(1899, 11, 30)) / 8.64e7);
// Get decimal part of day, OADate always assumes 24 hours in day
var partDay = (Math.abs((date - temp) % 8.64e7) / 8.64e7).toFixed(10);
return days + partDay.substr(1);
}
var now = new Date();
var x = dateToOADate(now);
console.log('Now: ' + now.toString());
console.log('As an OADate: ' + x);
console.log('Back to date: ' + dateFromOADate(x).toString());
window.onload = function(){
var el = document.getElementById('in')
el.addEventListener('change', function() {
var oaDate = dateToOADate(new Date(new Date(el.value)));
document.getElementById('out').value = oaDate;
document.getElementById('out2').value = dateFromOADate(oaDate);
});
}
input {width: 25em}
<table>
<tr>
<td>Input date:<br>(DD MMM YYYY HH:mm)
<td><input id="in" value="29 Dec 1899 06:00">
<tr>
<td>OA Date:
<td><input id="out" readonly>
<tr>
<td>Back to standard date:
<td><input id="out2" readonly>
</table>

Related

Checking if a month has passed from a date in string format(JS)

In my JavaScript application I'm receiving a date in a string format, like this: 19/10/2021 (dd/mm/yyyy). I want to check if a month has passed since said date and return a true if so. I'm trying something like the following code, but it isn't working.
I'm getting some weird values when I try debugging it with console.logs and such, I'm a newbie in js so I don't know where I'm doing stuff wrong.
var q = new Date();
var d = q.getDate();
var m = q.getMonth() + 1; //+1 because january is 0 and etc
var y = q.getFullYear();
var today = new Date(d, m, y);
mydate = userDate; // this is the string the app is receiving
if (today - mydate > 30) {
return true;
} else {
return false;
}
Thanks in advance.
First, when you set q to new Date() it is today. There's no need to get from it the day, month, and year and then set it again. So for today you can just do var today = new Date().
Secound, you should pass into Date() y,m,d and not d,m,y.
Third, if you subtract a date from another, the calculation will be on milisecounds, not days.
This should work:
var userDate = '19/10/2021';
var myDate = new Date(userDate.split('/').reverse());
var today = new Date();
var thirtyDays = 1000*60*60*24*30;
return today - myDate > thirtyDays;
Try this:
var q = new Date();
var d = q.getDate();
var m = q.getMonth();
var y = q.getFullYear();
var today = new Date(y,m,d);
var mydate = new Date("2021-11-22");
if(((today - mydate)/ (1000 * 60 * 60 * 24)) > 30)
{
return true;
}
else
{
return false;
}
Because the definition of "age in months" is... flexible, the easiest way is to use a little arithmetic as you would compute it in your head, and not involve the Date class.
For the [a] human interpretation of "age in months", the rule is
Compute the difference between the two dates in months,
as if the day-of-the-month was the 1st of the month for both dates
Subtract 1 to exclude the final month
Then, if the day-of-the-month of the last day of the period is on
or after the day-of-the-month of the first day of the period, the [potentially partial] final month is complete: add 1 to restore the count
The one fly in the ointment is, since months contain different numbers of days, dealing with the cases where the 2 months differ in their number of days.
If, however, the end month is shorter than the start month, you can get into a situation where the boundary condition can never be met (e.g., the start date is the February 28th and the end date is March 31st. To fix that, you need to look at the "end of the month" as being a window ranging from the last day of the start month through the last day of the end month inclusive.
That leads to this code. I'm using a structure like the following to represent a date:
{
year: 2021 , // 4-digit year
month: 11 , // month of year (1-12 mapping to January-December)
day: 23 // day of month (1-[28-31] depending on year/month
}
Ensuring that the data in that struct represents a valid date is left as an exercise for the reader.
The code is not that complicated:
/**
*
* #param {object} bgn - start date of period
* #param {number} bgn.year - 4-digit year
* #param {number} bgn.month - month of year [1-12]
* #param {number} bgn.day - day of month [1-31]
*
* #param {object} end - end date of period
* #param {number} end.year - 4-digit year
* #param {number} end.month - month of year [1-12]
* #param {number} end.day - day of month [1-31]
*
*/
function diffInMonths( bgn , end ) {
const between = ( x , min , max ) => x >= min && x <= max;
// We'll need to add back the final month based on the following:
// - end.day >= bgn.day -- we've passed the month boundary, or
// - end.day is within the end-of-month window
// (when the end month is shorter than the start month)
const needAdjustment = end.day >= bgn.day
|| between( end.day, daysInMonth(bgn), daysInMonth(end) );
const finalMonthAdjustment = needsAdjustment ? 1 : 0;
const deltaM = 12 * ( end.year - bgn.year )
+ ( end.month - bgn.month )
- 1 // remove the final month from the equation
+ finalMonthAdjustment // add in the precomputed final month adjustment
;
return deltaM;
}
/**
*
* #param {object} dt - date
* #param {number} dt.year - 4-digit year
* #param {number} dt.month - month of year [1-12]
* #param {number} dt.day - day of month [1-31]
*
*/
function daysInMonth(dt) {
const leapYear = ( dt.year % 4 === 0 && dt.year % 100 !== 0 ) || dt.year % 400 === 0;
const monthDays = leapYear ? daysPerMonthLeap : daysPerMonth;
const days = monthDays[dt.month];
return days;
}
// jan feb mar apr may jun jul aug sep oct nov dec
// ---------- --- --- --- --- --- --- --- --- --- --- --- ---
const daysPerMonth = [ undefined, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, ];
const daysPerMonthLeap = [ undefined, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, ];
The problem is that you are subtracting a string from date. You need mydate to be the same
type as today.
mydate = new Date(userDate)
(Note: This only works with 'month/day/year' format

How do I construct a javascript date using a 'day of the year (0 - 365)'? [duplicate]

I want to take a day of the year and convert to an actual date using the Date object. Example: day 257 of 1929, how can I go about doing this?
"I want to take a day of the year and convert to an actual date using the Date object."
After re-reading your question, it sounds like you have a year number, and an arbitrary day number (e.g. a number within 0..365 (or 366 for a leap year)), and you want to get a date from that.
For example:
dateFromDay(2010, 301); // "Thu Oct 28 2010", today ;)
dateFromDay(2010, 365); // "Fri Dec 31 2010"
If it's that, can be done easily:
function dateFromDay(year, day){
var date = new Date(year, 0); // initialize a date in `year-01-01`
return new Date(date.setDate(day)); // add the number of days
}
You could add also some validation, to ensure that the day number is withing the range of days in the year supplied.
The shortest possible way is to create a new date object with the given year, January as month and your day of the year as date:
const date = new Date(2017, 0, 365);
console.log(date.toLocaleDateString());
As for setDate the correct month gets calculated if the given date is larger than the month's length.
// You might need both parts of it-
Date.fromDayofYear= function(n, y){
if(!y) y= new Date().getFullYear();
var d= new Date(y, 0, 1);
return new Date(d.setMonth(0, n));
}
Date.prototype.dayofYear= function(){
var d= new Date(this.getFullYear(), 0, 0);
return Math.floor((this-d)/8.64e+7);
}
var d=new Date().dayofYear();
//
alert('day#'+d+' is '+Date.fromDayofYear(d).toLocaleDateString())
/* returned value: (String)
day#301 is Thursday, October 28, 2010
*/
Here is a function that takes a day number, and returns the date object
optionally, it takes a year in YYYY format for parameter 2. If you leave it off, it will default to current year.
var getDateFromDayNum = function(dayNum, year){
var date = new Date();
if(year){
date.setFullYear(year);
}
date.setMonth(0);
date.setDate(0);
var timeOfFirst = date.getTime(); // this is the time in milliseconds of 1/1/YYYY
var dayMilli = 1000 * 60 * 60 * 24;
var dayNumMilli = dayNum * dayMilli;
date.setTime(timeOfFirst + dayNumMilli);
return date;
}
OUTPUT
// OUTPUT OF DAY 232 of year 1995
var pastDate = getDateFromDayNum(232,1995)
console.log("PAST DATE: " , pastDate);
PAST DATE: Sun Aug 20 1995 09:47:18 GMT-0400 (EDT)
Here's my implementation, which supports fractional days. The concept is simple: get the unix timestamp of midnight on the first day of the year, then multiply the desired day by the number of milliseconds in a day.
/**
* Converts day of the year to a unix timestamp
* #param {Number} dayOfYear 1-365, with support for floats
* #param {Number} year (optional) 2 or 4 digit year representation. Defaults to
* current year.
* #return {Number} Unix timestamp (ms precision)
*/
function dayOfYearToTimestamp(dayOfYear, year) {
year = year || (new Date()).getFullYear();
var dayMS = 1000 * 60 * 60 * 24;
// Note the Z, forcing this to UTC time. Without this it would be a local time, which would have to be further adjusted to account for timezone.
var yearStart = new Date('1/1/' + year + ' 0:0:0 Z');
return yearStart + ((dayOfYear - 1) * dayMS);
}
// usage
// 2015-01-01T00:00:00.000Z
console.log(new Date(dayOfYearToTimestamp(1, 2015)));
// support for fractional day (for satellite TLE propagation, etc)
// 2015-06-29T12:19:03.437Z
console.log(new Date(dayOfYearToTimestamp(180.51323423, 2015)).toISOString);
If I understand your question correctly, you can do that from the Date constructor like this
new Date(year, month, day, hours, minutes, seconds, milliseconds)
All arguments as integers
You have a few options;
If you're using a standard format, you can do something like:
new Date(dateStr);
If you'd rather be safe about it, you could do:
var date, timestamp;
try {
timestamp = Date.parse(dateStr);
} catch(e) {}
if(timestamp)
date = new Date(timestamp);
or simply,
new Date(Date.parse(dateStr));
Or, if you have an arbitrary format, split the string/parse it into units, and do:
new Date(year, month - 1, day)
Example of the last:
var dateStr = '28/10/2010'; // uncommon US short date
var dateArr = dateStr.split('/');
var dateObj = new Date(dateArr[2], parseInt(dateArr[1]) - 1, dateArr[0]);
this also works ..
function to2(x) { return ("0"+x).slice(-2); }
function formatDate(d){
return d.getFullYear()+"-"+to2(d.getMonth()+1)+"-"+to2(d.getDate());
}
document.write(formatDate(new Date(2016,0,257)));
prints "2016-09-13"
which is correct as 2016 is a leaap year. (see calendars here: http://disc.sci.gsfc.nasa.gov/julian_calendar.html )
If you always want a UTC date:
function getDateFromDayOfYear (year, day) {
return new Date(Date.UTC(year, 0, day))
}
console.log(getDateFromDayOfYear(2020, 1)) // 2020-01-01T00:00:00.000Z
console.log(getDateFromDayOfYear(2020, 305)) // 2020-10-31T00:00:00.000Z
console.log(getDateFromDayOfYear(2020, 366)) // 2020-12-31T00:00:00.000Z

JavaScript -- get current date using UTC offset

How can I get the current date based on UTC Offset? For example, the UTC Offset for Australia is UTC +10:00 where it is already May 24th.
I can get UTC date and hour but can't find any Date methods that factor in UTC Offset.
Once you have the offset (in this case 10 hours) use this function:
function getDateWithUTCOffset(inputTzOffset){
var now = new Date(); // get the current time
var currentTzOffset = -now.getTimezoneOffset() / 60 // in hours, i.e. -4 in NY
var deltaTzOffset = inputTzOffset - currentTzOffset; // timezone diff
var nowTimestamp = now.getTime(); // get the number of milliseconds since unix epoch
var deltaTzOffsetMilli = deltaTzOffset * 1000 * 60 * 60; // convert hours to milliseconds (tzOffsetMilli*1000*60*60)
var outputDate = new Date(nowTimestamp + deltaTzOffsetMilli) // your new Date object with the timezone offset applied.
return outputDate;
}
In your case you would use:
var timeInAustralia = getDateWithUTCOffset(10);
This will return a Date object. You still need to format the date to your liking.
I agree with #Frax, Moment is a great library if you don't mind adding additional dependencies to your project.
Good luck
Using Moment.js and Moment Timezone it's very easy:
moment().tz("Australia/Sydney").format()
Date objects have UTC methods, so if you have an offset like +10:00 you can simply apply it to the UTC time and then read the resulting UTC values. The offset can be applied as hours and minutes, or converted to a single value and applied, e.g.
/* Return a date in yyyy-mm-dd format for the provided offset
** #param {string} offset - offset from GMT in format +/-hh:mm
** - default sign is +, default offset is 00:00
** #returns {string} date at pffset in format yyyy-mm-dd
*/
function dateAtOffset(offset){
function z(n){return (n<10?'0':'') + n}
var d = new Date();
var sign = /^\-/.test(offset)? -1 : +1;
offset = offset.match(/\d\d/g) || [0,0];
d.setUTCMinutes(d.getUTCMinutes() + sign*(offset[0]*60 + offset[1]*1))
return d.getUTCFullYear() + '-' + z(d.getUTCMonth() + 1) + '-' + z(d.getUTCDate());
}
var offset = '+10:00';
document.write('The date at GMT' + offset + ' is: ' + dateAtOffset(offset));
You can also adjust a date for the offset and read "local" values:
function timeAtOffset(offset) {
var d = new Date();
var sign = /^\-/.test(offset)? -1 : 1;
offset = offset.match(/\d\d/g) || [0,0];
d.setMinutes(d.getMinutes() + d.getTimezoneOffset() + sign*(offset[0]*60 + offset[1]*1));
return d;
}
var offset = '-04:00';
document.write('Time at GMT' + offset + ' is: ' + timeAtOffset(offset))
Note however that the default toString will report the local time zone offset, not the one to which it has been adjusted, so be careful when using such an object.

How do I convert UTC/ GMT datetime to CST in Javascript? (not local, CST always)

I have a challenge where backend data is always stored in UTC time. Our front-end data is always presented in CST. I don't have access to this 'black box.'
I would like to mirror this in our data warehouse. Which is based in Europe (CET). So "local" conversion will not work.
I'm wondering the simplest, most straightforward way to accurately convert UTC time (I can have it in epoch milliseconds or a date format '2015-01-01 00:00:00') to Central Standard Time. (which is 5 or 6 hours behind based on Daylight Savings).
I see a lot of threads about converting to 'local' time ... again I don't want this, nor do I simply want to subtract 6 hours which will be wrong half the year.
Anyone have any ideas? This seems to be a very common problem but I've been searching for a while, and have found nothing.
Using moment.js with the moment-timezone add-on makes this task simple.
// construct a moment object with UTC-based input
var m = moment.utc('2015-01-01 00:00:00');
// convert using the TZDB identifier for US Central time
m.tz('America/Chicago');
// format output however you desire
var s = m.format("YYYY-MM-DD HH:mm:ss");
Additionally, since you are referring to the entire North American Central time zone, you should say either "Central Time", or "CT". The abbreviation "CST" as applied to North America explicitly means UTC-6, while the "CDT" abbreviation would be used for UTC-5 during daylight saving time.
Do be careful with abbreviations though. "CST" might mean "China Standard Time". (It actually has five different interpretations).
You can use the time zone offset to determine whether 5 or 6 hours should be subtracted.
var dateJan;
var dateJul;
var timezoneOffset;
var divUTC;
var divCST;
// Set initial date value
dateValue = new Date('10/31/2015 7:29:54 PM');
divUTC = document.getElementById('UTC_Time');
divCST = document.getElementById('CST_Time');
divUTC.innerHTML = 'from UTC = ' + dateValue.toString();
// Get dates for January and July
dateJan = new Date(dateValue.getFullYear(), 0, 1);
dateJul = new Date(dateValue.getFullYear(), 6, 1);
// Get timezone offset
timezoneOffset = Math.max(dateJan.getTimezoneOffset(), dateJul.getTimezoneOffset());
// Check if daylight savings
if (dateValue.getTimezoneOffset() < timezoneOffset) {
// Adjust date by 5 hours
dateValue = new Date(dateValue.getTime() - ((1 * 60 * 60 * 1000) * 5));
}
else {
// Adjust date by 6 hours
dateValue = new Date(dateValue.getTime() - ((1 * 60 * 60 * 1000) * 6));
}
divCST.innerHTML = 'to CST = ' + dateValue.toString();
<div id="UTC_Time"></div>
<br/>
<div id="CST_Time"></div>
Maybe you can use something like the following. Note, that is just an example you might need to adjust it to your needs.
let cstTime = new Date(createdAt).toLocaleString("es-MX", {
timeZone: "America/Mexico_City" });
You can use below code snippet for converting.
function convertUTCtoCDT() {
var timelagging = 6; // 5 or 6
var utc = new Date();
var cdt = new Date(utc.getTime()-((1 * 60 * 60 * 1000) * timelagging));
console.log("CDT: "+cdt);
}
let newDate = moment(new Date()).utc().format("YYYY-MM-DD HH:mm:ss").toString()
var m = moment.utc(newDate);
m.tz('America/Chicago');
var cstDate = m.format("YYYY-MM-DD HH:mm:ss");
You can use below code snippet
// Get time zone offset for CDT or CST
const getCdtCstOffset = () => {
const getNthSunday = (date, nth) => {
date.setDate((7*(nth-1))+(8-date.getDay()));
return date;
}
const isCdtTimezoneOffset = (today) => {
console.log('Today : ', today);
let dt = new Date();
var mar = new Date(dt.getFullYear(), 2, 1);
mar = getNthSunday(mar, 2);
console.log('CDT Start : ', mar);
var nov = new Date(dt.getFullYear(), 10, 1, 23, 59, 59);
nov = getNthSunday(nov, 1);
console.log('CDT End : ', nov);
return mar.getTime()< today.getTime() && nov.getTime()> today.getTime();
}
var today = new Date()// current date
if (isCdtTimezoneOffset(today)) {
return -5
} else {
return -6
}
}
let cstOrCdt = new Date();
cstOrCdt.setHours(cstOrCdt.getHours()+getCdtCstOffset())
console.log('CstOrCdt : ', cstOrCdt);

Add future time to date and compare

I apologize if this question has been asked already but I couldn't find it for my problem.
I have seen this but am not sure what the number it returns represents: Date() * 1 * 10 * 1000
I'd like to set a future moment in time, and then compare it to the current instance of Date() to see which is greater. It could be a few seconds, a few minutes, a few hours or a few days in the future.
Here is the code that I have:
var futureMoment = new Date() * 1 *10 * 1000;
console.log('futureMoment = ' + futureMoment);
var currentMoment = new Date();
console.log('currentMoment = ' + currentMoment);
if ( currentMoment < futureMoment) {
console.log('currentMoment is less than futureMoment. item IS NOT expired yet');
}
else {
console.log('currentMoment is MORE than futureMoment. item IS expired');
}
Javascript date is based on the number of milliseconds since the Epoch (1 Jan 1970 00:00:00 UTC).
Therefore, to calculate a future date you add milliseconds.
var d = new Date();
var msecSinceEpoch = d.getTime(); // date now
var day = 24 * 60 * 60 * 1000; // 24hr * 60min * 60sec * 1000msec
var futureDate = new Date(msecSinceEpoc + day);
See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date
var futureMoment = new Date() * 1 *10 * 1000;
becomes
var now = new Date();
var futureMoment = new Date(now.getTime() + 1 *10 * 1000);
I think you mean to add time. Not multiply it.
If you deal with time, there is a lot of tools to choose.
Try moment library.
Used following code to compare selected date time with current date time
var dt = "Thu Feb 04 2016 13:20:02 GMT+0530 (India Standard Time)"; //this date format will receive from input type "date"..
function compareIsPastDate(dt) {
var currDtObj = new Date();
var currentTime = currDtObj.getTime();
var enterDtObj = new Date(dt);
var enteredTime = enterDtObj.getTime();
return (currentTime > enteredTime);
}

Categories

Resources