showing ETA in 12 hours format react native - javascript

does any one know this could be achieved in react native, I am working on an location based app that requires showing ETA to the customer. However, I do not want to show just 25mins away, I would like to implement 'arriving 'Arriving Today, 9:45 AM. which implies the current time is 9:20 and the ETA is added to the current time.
something like the image below

You can achieve it using the below function:
getETA(minutesLeftInArrival) {
let arrivalTimeLeft = minutesLeftInArrival * 60 * 1000; // convert to unix timestamp
let currentTime = Date.now(); //TIME RIGHT NOW
let timeToArrive = currentTime + arrivalTimeLeft; // TIME OF ARRIVAL
let time = new Date(timeToArrive).toTimeString(); // TIME in 24 hour format
time = time.split(" ")[0]; // Remove GMT+...... from time
time = time.replace(/:\d\d([ ap]|$)/,'$1'); // remove seconds from time
let H = +time.substr(0, 2);
let hour = H % 12 || 12;
let ampm = (H < 12 || H === 24) ? "AM" : "PM"; // Return AM or PM depedning of 24 Hour time
time = hour + time.substr(2, 3) + " " + ampm;
return time; // RETURNS 12 HOUR TIME
}
https://snack.expo.io/#ammarahmed/getetatime

Related

How to get current hour in milliseconds since epoch? [duplicate]

I am working on a project that requires a time in the future to be set using the Date object.
For example:
futureTime = new Date();
futureTime.setHours(futureTime.getHours()+2);
My questions is; once the future date is set, how can I round to the closest full hour and then set the futureTime var with it?
For example:
Given 8:55 => var futureTime = 9:00
Given 16:23 => var futureTime = 16:00
Any help would be appreciated!
Round the minutes and then clear the minutes:
var date = new Date(2011,1,1,4,55); // 4:55
roundMinutes(date); // 5:00
function roundMinutes(date) {
date.setHours(date.getHours() + Math.round(date.getMinutes()/60));
date.setMinutes(0, 0, 0); // Resets also seconds and milliseconds
return date;
}
The other answers ignore seconds and milliseconds components of the date.
The accepted answer has been updated to handle milliseconds, but it still does not handle daylight savings time properly.
I would do something like this:
function roundToHour(date) {
p = 60 * 60 * 1000; // milliseconds in an hour
return new Date(Math.round(date.getTime() / p ) * p);
}
var date = new Date(2011,1,1,4,55); // 4:55
roundToHour(date); // 5:00
date = new Date(2011,1,1,4,25); // 4:25
roundToHour(date); // 4:00
A slightly simpler way :
var d = new Date();
d.setMinutes (d.getMinutes() + 30);
d.setMinutes (0);
Another solution, which is no where near as graceful as IAbstractDownvoteFactory's
var d = new Date();
if(d.getMinutes() >= 30) {
d.setHours(d.getHours() + 1);
}
d.setMinutes(0);
Or you could mix the two for optimal size.
http://jsfiddle.net/HkEZ7/
function roundMinutes(date) {
return date.getMinutes() >= 30 ? date.getHours() + 1 : date.getHours();
}
As a matter of fact Javascript does this default which gives wrong time.
let dateutc="2022-02-17T07:20:00.000Z";
let bd = new Date(dateutc);
console.log(bd.getHours()); // gives me 8!!!!!
it is even wrong for my local time because I am GMT+2 so it should say 9.
moment.js also does it wrong so you need to be VERY carefull
Pass any cycle you want in milliseconds to get next cycle example 1 hours
function calculateNextCycle(interval) {
const timeStampCurrentOrOldDate = Date.now();
const timeStampStartOfDay = new Date().setHours(0, 0, 0, 0);
const timeDiff = timeStampCurrentOrOldDate - timeStampStartOfDay;
const mod = Math.ceil(timeDiff / interval);
return new Date(timeStampStartOfDay + (mod * interval));
}
console.log(calculateNextCycle(1 * 60 * 60 * 1000)); // 1 hours in milliseconds

UTC javascript countdown goes negative in browser

I am trying to make a JavaScript countdown timer to UTC midnight that works in a browser (which typically converts to local time).
It seems to work most of the time, but for some reason it will go negative sometimes. I want it to always display time until midnight UTC.
-3 hours 23 minutes 34 seconds
I'm pretty sure I tested this on crossing midnight, but lately it's been going negative like it isn't pulling a new date.
Here is what I am using now on my website.
setInterval(() => {
let toDate = new Date()
let tomorrow = new Date()
tomorrow.setHours(24, 0, 0, 0)
let diffMS =
tomorrow.getTime() / 1000 -
toDate.getTime() / 1000 -
toDate.getTimezoneOffset() * 60
let diffHr = Math.floor(diffMS / 3600)
diffMS = diffMS - diffHr * 3600
let diffMi = Math.floor(diffMS / 60)
diffMS = diffMS - diffMi * 60
let diffS = Math.floor(diffMS)
let result = diffHr + ' hours '
result += diffMi + ' minutes '
result += diffS + ' seconds '
this.timeRemaining = result
}, 1000)
Not sure exactly where your issue is from, but using local time adjusted by offset is somewhat fraught. Also the offset changes over a DST boundary so that might be an issue too (or not) so the countdown will jump the equivalent of the change in offset (either + or -).
It's very much simpler to set the end using UTC methods and count down to that, e.g.
// Return time to next UTC midnight as x hours x minutes x seconds
function toMidnightUTC(date = new Date()) {
let d = new Date(+date);
d.setUTCHours(24,0,0,0);
let diff = d - date;
return `${diff/3.6e6 |0} hours ` +
`${diff%3.6e6 / 6e4 |0} minutes ` +
`${diff%6e4 / 1000 |0} seconds`;
}
// Run 20ms after next full second
let runIt = ()=> {
document.getElementById('s0').textContent = toMidnightUTC();
let lag = 1020 - new Date() % 6e4;
setTimeout(runIt, lag);
};
// Start the process…
runIt();
<span id="s0"></span>
Note that setInterval isn't a good way to do a countdown as the interval is not guaranteed to run every second and typically slowly drifts so it doesn't tick with the system clock and drifts, so skips a second from time to time.
Better to use setTimeout and get the time to the next full second each time so it runs very close to the system clock tick and rarely skips (though it still might if the system is working hard).

Not counting down time correctly

I am creating a countdown website. I want it to count down from the current time the my celebration date 2019-11-29 00:00:00. I want the timezone to be in Australia Brisbane time zone. However, it seems to be that it keeps calculating the amount of time left till my celebration date wrong. Could someone tell me what I did wrong? And once the time hits 0, how can I get rid of the countdown and replace it with Its celebration time
function dateDiff(a, b) {
// Some utility functions:
const getSecs = dt => (dt.getHours() * 24 + dt.getMinutes()) * 60 + dt.getSeconds();
const getMonths = dt => dt.getFullYear() * 12 + dt.getMonth();
// 0. Convert to new date objects to avoid side effects
a = new Date(a);
b = new Date(b);
if (a > b) [a, b] = [b, a]; // Swap into order
// 1. Get difference in number of seconds during the day:
let diff = getSecs(b) - getSecs(a);
if (diff < 0) {
b.setDate(b.getDate()-1); // go back one day
diff += 24*60*60; // compensate with the equivalent of one day
}
// 2. Get difference in number of days of the month
let days = b.getDate() - a.getDate();
if (days < 0) {
b.setDate(0); // go back to (last day of) previous month
days += b.getDate(); // compensate with the equivalent of one month
}
// 3. Get difference in number of months
const months = getMonths(b) - getMonths(a);
return {
years: Math.floor(months/12),
months: months % 12,
days,
hours: Math.floor(diff/3600),
minutes: Math.floor(diff/60) % 24,
seconds: diff % 60
};
}
// Date to start on
var celebrationDate = new Date("2019-11-29 00:00:00").toLocaleString("en-US", {timeZone: "Australia/Brisbane"});
// Update the count every 1 second
!function refresh () {
const diff = dateDiff(new Date().toLocaleString("en-US", {timeZone: "Australia/Brisbane"}), celebrationDate);
document.getElementById("day-val").innerHTML = diff[Object.keys(diff)[2]];
document.getElementById("hour-val").innerHTML = diff[Object.keys(diff)[3]];
document.getElementById("min-val").innerHTML = diff[Object.keys(diff)[4]];
document.getElementById("sec-val").innerHTML = diff[Object.keys(diff)[5]];
setTimeout(refresh, 1000)
}()
<div id="day-val"></div><div>Days</div><br>
<div id="hour-val"></div><div>Hours</div><br>
<div id="min-val"></div><div>Minutes</div><br>
<div id="sec-val"></div><div>Seconds</div>
IF you are using moment.js
What you can do is use the diff and duration functions like so:
const now = moment();
const celebrationDate= moment("2019-11-30 00:00:00");
// this will get the difference between now and celebrationDate
const celebrationDateDiff = expiration.diff(now);
// convert it into duration
const duration = moment.duration(celebrationDateDiff);
You can then access the countdown like:
duration.days() // will return the number of days
duration.hours() // will return the number of remaining hours
duration.minutes() // will return the number of remaining minutes
Solution with plain javascript:
Get the clients time zone offset
Calculate the diff between client offset and "Australian/Brisbane" offset
Calculate time left by targetDate - currentDate - offsetDiff
Format the result to display it
Example:
const minToMS = min => min * 60 * 1000
const getCountDownFromMS = diff => {
const milliseconds = diff % 1000
diff = (diff - milliseconds) / 1000
const seconds = diff % 60
diff = (diff - seconds) / 60
const minutes = diff % 60
diff = (diff - minutes) / 60
const hours = diff % 24
diff = (diff - hours) / 24
const days = diff
return {
days,
hours,
minutes,
seconds,
milliseconds
}
}
const targetDate = new Date('2019-11-29 00:00:00')
// Getting offset with getTimezoneOffset is not reliable, using a database to get time zone offset is needed, like IANA Time Zone Database.
// moment.js internally uses IANA db
const tzOffset = targetDate.getTimezoneOffset() // Client browsers timezone offset in minutes
const target_tzOffset = -600 // Australia Brisbane timezone offset in minutes
const offset = minToMS(tzOffset - target_tzOffset)
const msLeft = targetDate - new Date() - offset
const result = getCountDownFromMS(msLeft)
You should also check moment.js as it has many useful features.
Example with moment.js:
const now = moment()
const target = moment.tz('2019-11-29 00:00:00', 'Australia/Brisbane')
const result = moment.duration(target.diff(now))

Converting Excel Time to moment.js

I have an Electron app where an Excel-Sheet with a couple of columns containing time values needs to be imported. In my app those values are converted in a loop to momentjs object for further manipulation:
x['Time'] = moment(x['Time'], ['HH:mm','HH:mm:ss']).format('HH:mm:ss');
This works fine as long the Excel contains time values formatted as text. But if the Excel is set up the way it's meant to be, then the value of the Cell is a Number between 0 and 1 (Excel counts time internally as floating point - so e.g. 0,5 translates to 12:00:00).
Does anyone know how I can translate that back to a readable Timevalue for momentjs?
export const parseDateExcel = (excelTimestamp) => {
const secondsInDay = 24 * 60 * 60;
const excelEpoch = new Date(1899, 11, 31);
const excelEpochAsUnixTimestamp = excelEpoch.getTime();
const missingLeapYearDay = secondsInDay * 1000;
const delta = excelEpochAsUnixTimestamp - missingLeapYearDay;
const excelTimestampAsUnixTimestamp = excelTimestamp * secondsInDay * 1000;
const parsed = excelTimestampAsUnixTimestamp + delta;
return isNaN(parsed) ? null : parsed;
};
Usage:
new Date(parseDateExcel(36902.49097)) //=> Thu Jan 11 2001 11:46:59 GMT+0000 (Greenwich Mean Time)
Source
This is as far as I have work with the Excel time decimal values.
So according to Excel the time text is represented by a decimal number ranging from 0 to 1.
function excelDateToJSDate(excel_date, time = false) {
let day_time = excel_date % 1
let meridiem = "AMPM"
let hour = Math.floor(day_time * 24)
let minute = Math.floor(Math.abs(day_time * 24 * 60) % 60)
let second = Math.floor(Math.abs(day_time * 24 * 60 * 60) % 60)
hour >= 12 ? meridiem = meridiem.slice(2, 4) : meridiem = meridiem.slice(0, 2)
hour > 12 ? hour = hour - 12 : hour = hour
hour = hour < 10 ? "0" + hour : hour
minute = minute < 10 ? "0" + minute : minute
second = second < 10 ? "0" + second : second
let daytime = "" + hour + ":" + minute + ":" + second + " " + meridiem
return time ? daytime : (new Date(0, 0, excel_date, 0, -new Date(0).getTimezoneOffset(), 0)).toLocaleDateString(navigator.language, {}) + " " + daytime
};
First we define the midday, then handle the hours, minutes and seconds, then verify if the given hour is either AM or PM, as a formatting fashion preference we change the 24 hours to 12 hour convention and add padding zeros to any value less than 10 and lastly return the time or date as a string.
Example
function excelDateToJSDate(excel_date, time = false) {
let day_time = excel_date % 1
let meridiem = "AMPM"
let hour = Math.floor(day_time * 24)
let minute = Math.floor(Math.abs(day_time * 24 * 60) % 60)
let second = Math.floor(Math.abs(day_time * 24 * 60 * 60) % 60)
hour >= 12 ? meridiem = meridiem.slice(2, 4) : meridiem = meridiem.slice(0, 2)
hour > 12 ? hour = hour - 12 : hour = hour
hour = hour < 10 ? "0" + hour : hour
minute = minute < 10 ? "0" + minute : minute
second = second < 10 ? "0" + second : second
let daytime = "" + hour + ":" + minute + ":" + second + " " + meridiem
return time ? daytime : (new Date(0, 0, excel_date, 0, -new Date(0).getTimezoneOffset(), 0)).toLocaleDateString(navigator.language, {}) + " " + daytime
};
console.log(excelDateToJSDate(0.125, true));
console.log(excelDateToJSDate(43556));
Due to the fact I could not find a real answer, here is one that worked for me:
let fromExcel = 0,709722222222222; //translates to 17:02:00
let basenumber = (fromExcel*24)
let hour = Math.floor(basenumber).toString();
if (hour.length < 2) {
hour = '0'+hour;
}
var minute = Math.round((basenumber % 1)*60).toString();
if (minute.length < 2) {
minute = '0'+minute;
}
let Timestring = (hour+':'+minute+':00');
So I have a String momentjscan translate. The reason I do not mark this as answer is that there sure are nicer ways of conversion and I could not find a solution to calculate the seconds (which in my special case does not matter, as I do not use them).

How to add hours to a Date object?

It amazes me that JavaScript's Date object does not implement an add function of any kind.
I simply want a function that can do this:
var now = Date.now();
var fourHoursLater = now.addHours(4);
function Date.prototype.addHours(h) {
// How do I implement this?
}
I would simply like some pointers in a direction.
Do I need to do string parsing?
Can I use setTime?
How about milliseconds?
Like this:
new Date(milliseconds + 4*3600*1000 /* 4 hours in ms */)?
This seems really hackish though - and does it even work?
JavaScript itself has terrible Date/Time API's. Nonetheless, you can do this in pure JavaScript:
Date.prototype.addHours = function(h) {
this.setTime(this.getTime() + (h*60*60*1000));
return this;
}
Date.prototype.addHours= function(h){
this.setHours(this.getHours()+h);
return this;
}
Test:
alert(new Date().addHours(4));
The below code will add 4 hours to a date (example, today's date):
var today = new Date();
today.setHours(today.getHours() + 4);
It will not cause an error if you try to add 4 to 23 (see the documentation):
If a parameter you specify is outside of the expected range, setHours() attempts to update the date information in the Date object accordingly
It is probably better to make the addHours method immutable by returning a copy of the Date object rather than mutating its parameter.
Date.prototype.addHours= function(h){
var copiedDate = new Date(this.getTime());
copiedDate.setHours(copiedDate.getHours()+h);
return copiedDate;
}
This way you can chain a bunch of method calls without worrying about state.
The version suggested by kennebec will fail when changing to or from DST, since it is the hour number that is set.
this.setUTCHours(this.getUTCHours()+h);
will add h hours to this independent of time system peculiarities.
Jason Harwig's method works as well.
Get a date exactly two hours from now, in one line.
You need to pass milliseconds to new Date.
let expiryDate = new Date(new Date().setHours(new Date().getHours() + 2));
or
let expiryDate2 = new Date(Date.now() + 2 * (60 * 60 * 1000) );
let nowDate = new Date();
let expiryDate = new Date(new Date().setHours(new Date().getHours() + 2));
let expiryDate2 = new Date(Date.now() + 2 * (60 * 60 * 1000) );
console.log('now', nowDate);
console.log('expiry', expiryDate);
console.log('expiry 2', expiryDate2);
You can use the Moment.js library.
var moment = require('moment');
foo = new moment(something).add(10, 'm').toDate();
I also think the original object should not be modified. So to save future manpower here's a combined solution based on Jason Harwig's and Tahir Hasan answers:
Date.prototype.addHours= function(h){
var copiedDate = new Date();
copiedDate.setTime(this.getTime() + (h*60*60*1000));
return copiedDate;
}
If you would like to do it in a more functional way (immutability) I would return a new date object instead of modifying the existing and I wouldn't alter the prototype but create a standalone function. Here is the example:
//JS
function addHoursToDate(date, hours) {
return new Date(new Date(date).setHours(date.getHours() + hours));
}
//TS
function addHoursToDate(date: Date, hours: number): Date {
return new Date(new Date(date).setHours(date.getHours() + hours));
}
let myDate = new Date();
console.log(myDate)
console.log(addHoursToDate(myDate,2))
There is an add in the Datejs library.
And here are the JavaScript date methods. kennebec wisely mentioned getHours() and setHours();
Check if it’s not already defined. Otherwise, define it in the Date prototype:
if (!Date.prototype.addHours) {
Date.prototype.addHours = function(h) {
this.setHours(this.getHours() + h);
return this;
};
}
This is an easy way to get an incremented or decremented data value.
const date = new Date()
const inc = 1000 * 60 * 60 // an hour
const dec = (1000 * 60 * 60) * -1 // an hour
const _date = new Date(date)
return new Date(_date.getTime() + inc)
return new Date(_date.getTime() + dec)
Another way to handle this is to convert the date to unixtime (epoch), then add the equivalent in (milli)seconds, then convert it back. This way you can handle day and month transitions, like adding 4 hours to 21, which should result in the next day, 01:00.
SPRBRN is correct. In order to account for the beginning/end of the month and year, you need to convert to Epoch and back.
Here's how you do that:
var milliseconds = 0; //amount of time from current date/time
var sec = 0; //(+): future
var min = 0; //(-): past
var hours = 2;
var days = 0;
var startDate = new Date(); //start date in local time (we'll use current time as an example)
var time = startDate.getTime(); //convert to milliseconds since epoch
//add time difference
var newTime = time + milliseconds + (1000*sec) + (1000*60*min) + (1000*60*60*hrs) + (1000*60*60*24*days);
var newDate = new Date(newTime); //convert back to date; in this example: 2 hours from right now
Or do it in one line (where variable names are the same as above:
var newDate =
new Date(startDate.getTime() + millisecond +
1000 * (sec + 60 * (min + 60 * (hours + 24 * days))));
For a simple add/subtract hour/minute function in JavaScript, try this:
function getTime (addHour, addMin){
addHour = (addHour ? addHour : 0);
addMin = (addMin ? addMin : 0);
var time = new Date(new Date().getTime());
var AM = true;
var ndble = 0;
var hours, newHour, overHour, newMin, overMin;
// Change form 24 to 12 hour clock
if(time.getHours() >= 13){
hours = time.getHours() - 12;
AM = (hours>=12 ? true : false);
}else{
hours = time.getHours();
AM = (hours>=12 ? false : true);
}
// Get the current minutes
var minutes = time.getMinutes();
// Set minute
if((minutes + addMin) >= 60 || (minutes + addMin) < 0){
overMin = (minutes + addMin) % 60;
overHour = Math.floor((minutes + addMin - Math.abs(overMin))/60);
if(overMin < 0){
overMin = overMin + 60;
overHour = overHour-Math.floor(overMin/60);
}
newMin = String((overMin<10 ? '0' : '') + overMin);
addHour = addHour + overHour;
}else{
newMin = minutes + addMin;
newMin = String((newMin<10 ? '0' : '') + newMin);
}
// Set hour
if((hours + addHour >= 13) || (hours + addHour <= 0)){
overHour = (hours + addHour) % 12;
ndble = Math.floor(Math.abs((hours + addHour)/12));
if(overHour <= 0){
newHour = overHour + 12;
if(overHour == 0){
ndble++;
}
}else{
if(overHour == 0){
newHour = 12;
ndble++;
}else{
ndble++;
newHour = overHour;
}
}
newHour = (newHour<10 ? '0' : '') + String(newHour);
AM = ((ndble + 1) % 2 === 0) ? AM : !AM;
}else{
AM = (hours + addHour == 12 ? !AM : AM);
newHour = String((Number(hours) + addHour < 10 ? '0': '') + (hours + addHour));
}
var am = (AM) ? 'AM' : 'PM';
return new Array(newHour, newMin, am);
};
This can be used without parameters to get the current time:
getTime();
Or with parameters to get the time with the added minutes/hours:
getTime(1, 30); // Adds 1.5 hours to current time
getTime(2); // Adds 2 hours to current time
getTime(0, 120); // Same as above
Even negative time works:
getTime(-1, -30); // Subtracts 1.5 hours from current time
This function returns an array of:
array([Hour], [Minute], [Meridian])
If you need it as a string, for example:
var defaultTime: new Date().getHours() + 1 + ":" + new Date().getMinutes();
I think this should do the trick
var nextHour = Date.now() + 1000 * 60 * 60;
console.log(nextHour)
You can even format the date in desired format using the moment function after adding 2 hours.
var time = moment(new Date(new Date().setHours(new Date().getHours() + 2))).format("YYYY-MM-DD");
console.log(time);
A little messy, but it works!
Given a date format like this: 2019-04-03T15:58
//Get the start date.
var start = $("#start_date").val();
//Split the date and time.
var startarray = start.split("T");
var date = startarray[0];
var time = startarray[1];
//Split the hours and minutes.
var timearray = time.split(":");
var hour = timearray[0];
var minute = timearray[1];
//Add an hour to the hour.
hour++;
//$("#end_date").val = start;
$("#end_date").val(""+date+"T"+hour+":"+minute+"");
Your output would be: 2019-04-03T16:58
The easiest way to do it is:
var d = new Date();
d = new Date(d.setHours(d.getHours() + 2));
It will add 2 hours to the current time.
The value of d = Sat Jan 30 2021 23:41:43 GMT+0500 (Pakistan Standard Time).
The value of d after adding 2 hours = Sun Jan 31 2021 01:41:43 GMT+0500 (Pakistan Standard Time).

Categories

Resources