How to format difference between 2 moment date - reactjs

There is start date and end date. Using moment ,will get difference between 2 dates in hours.
var now = moment(sessionData.StartTime);
var end = moment(sessionData.EndTime);
var duration = moment.duration(end.diff(now));
var days = duration.asHours();
it returns : 3.08 .
I want to show that difference like this- 3 hrs 15 m.
Is this possible to achieve

Try get the difference between two days using diff followed by expressing it terms of duration. Then you would be able to get exact number of days, hours, minutes
let now = moment("2017-01-26T14:21:22+0000");
let expiration = moment("2017-01-29T17:24:22+0000");
let diff = expiration.diff(now);
let diffDuration = moment.duration(diff);
let dayDiff = diffDuration.days() + "d";
let hoursDiff = diffDuration.hours() + "hrs";
let minDiff = diffDuration.minutes() + "m";
console.log(`${dayDiff} ${hoursDiff} ${minDiff}`);

Related

How can I calculate the difference between two dates in Luxon?

I'm doing a project in React js and I need calculate the difference between dates.
The first one the user choose the startTime(state) and the endTime(state) and the program give the differecen in years, months and days ( this program is done and working).
Now I'm trying calculate the difference in days between the day 1-01-2022 and other date that the user choose.
I have tryed change the format but I receive errors.
//this is working
const date1 = DateTime.fromISO(endTime.toISOString());
const date2 = DateTime.fromISO(startTime.toISOString());
let durationDate = date1.diff(date2, ["years", "months", "days"]);
//--------------
//this is not working
const date3 = DateTime.fromISO(endTime.toISOString());
const dateNow = DateTime.now().startOf("year").toISO();
let dateTermination = endTime.diff(dateNow, ["years", "months", "days"]).toObject();
//----------------

Google Earth Engine - counts days of the longest dry period in a time period

I'm trying to map the max number of consecutive days with rain <1 mm in Google Earth Engine.
This is the link to the code
https://code.earthengine.google.com/22b5c20d2700a2ffb5989f892838ac58
First I reclassify the collection with 0 if rain <=1 and 1 if >1.
Then I run the code that should count the days of the longest dry period, but it is able to do so only if the dry period reach the end of the time period.
For instance if I am looking for the longest dry period in 4 days timestep i get the following series:
rain days 1 2 3 4 output
0,0,1,1 = 0 dry days
0,1,0,0 = 2 dry days
0 = rain<=1 and
1 = rain>1 (as per the first step)
Does anyone can help in solving this?
Thanks
I don't think you were far off in your code that you provided. To keep track of the dry spells you have to use .iterate(). I took a stab at your application in a little different way where instead of classifying the data before the iteration, I calculate which pixels are dry each day and carry over the accumulated days that a pixel is dry, otherwise it is set to zero:
// DATA
var collection = ee.ImageCollection("UCSB-CHG/CHIRPS/DAILY");
// Define time range
var startyear = 2000;
var endyear = 2017;
var startmonth = 1;
var endmonth = 12;
// Set date in ee date format
var startdate = ee.Date.fromYMD(startyear,startmonth,1);
var enddate = ee.Date.fromYMD(endyear,endmonth,31);
// Filter data
var datain_t = collection.filterDate(startdate, enddate)
.filter(ee.Filter.calendarRange(startmonth,endmonth, 'month'))
.select("precipitation").map(function(img){
return img.addBands(ee.Image.constant(0).uint8().rename('counter'));
})
.sort('system:time_start');
// // START
var dataset = datain_t
.filterDate("2016-08-01","2016-08-30")
.sort('system:time_start:');
print(dataset,"dataset");
var precipThresh = 1; // mm
function drySpells(img, list){
// get previous image
var prev = ee.Image(ee.List(list).get(-1));
// find areas gt precipitation threshold (gt==0, lt==1)
var dry = img.select('precipitation').lt(precipThresh);
// add previous day counter to today's counter
var accum = prev.select('counter').add(dry).rename('counter');
// create a result image for iteration
// precip < thresh will equal the accumulation of counters
// otherwise it will equal zero
var out = img.select('precipitation').addBands(
img.select('counter').where(dry.eq(1),accum)
).uint8();
return ee.List(list).add(out);
}
// create first image for iteration
var first = ee.List([ee.Image(dataset.first())]);
// apply dry speall iteration function
var maxDrySpell = ee.ImageCollection.fromImages(
dataset.iterate(drySpells,first)
).max(); // get the max value
// display results
Map.addLayer(maxDrySpell.select('counter'),{min:0,max:30,palette:'#9ecae1,#ffffff,#ffeda0,#feb24c,#f03b20'},'Max Dry Spells');
Here is the link to the code: https://code.earthengine.google.com/80b4c0f7e82a5f0da316af1d2a55dd59
Don't try to run this analysis for too long of a time period or Earth Engine will give an error. I hope this helps!

get the difference between 2 date & time by hours, minutes and seconds using cakephp

I'm trying to get the difference between a datetime and a current datetime using cakephp . I succeeded to get it but I want to convert it to only hours ,minutes and seconds .
here is my code :
$currDateTime = Time::now();
$date1 = $plan->start_day->format('Y-m-d');
$date2 = $currDateTime->format('Y-m-d');
$diff = abs(strtotime($date1) - strtotime($date2));
$years = floor($diff / (365*60*60*24));
$months = floor(($diff - $years * 365*60*60*24) / (30*60*60*24));
$days = floor(($diff - $years * 365*60*60*24 - $months*30*60*60*24)/ (60*60*24)) ;
$time1 = $plan->start_day->format('H:i:s');
$time2 = $currDateTime->format('H:i:s');
$seconds = abs(strtotime($time1) - strtotime($time2));
$hours = floor($seconds / 3600);
$mins = floor(($seconds - ($hours*3600)) / 60);
$secs = floor($seconds % 60);
the result is a difference in years, months, days, hours, minutes and seconds.
how can I convert it to only H:m:s ??
There's no need for all these calculations, simply create a DateInterval diff using the diff() method provided by the time object, and use the days, h, i, and s values it provides to create your desired output. The only calculation that would be required, would be to add the days in hours.
$diff = $currDateTime->diff($plan->start_day);
$formatted = sprintf('%02d:%02d:%02d', ($diff->days * 24) + $diff->h, $diff->i, $diff->s);
See also
PHP Manual > Date/Time > DateTimeInterface > DateTimeInterface::diff
PHP Manual > Date/Time > DateInterval

Countdown Timer in Angular using $Interval()

I am implementing a function to have a countdown in Angular form current time - existing time in future. If the time has elapsed then display a message. Timer ran out in ..... HH:MM:SS
The end time. Lets call it endTime eg:
9/15/2016 9:16:00 PM
Current time. Time current moment we live.
Lets call it currentTime.
The goal is to get a timer that is Current time - end time. Save it to a Variable TotalHours.
Then calculate the time remaining for NOW to total hours. For example TotalHours = 5. And NOW is 9/14/2016 1:16:00 PM then FinalCountDown = 6:16:00 PM. That is the timer I want running...
Here is how I am doing it...
if (info.endTime) {
var CurrentTime = new Date().toLocaleString('en-US');
moment.locale(); // en
var TotalHours = moment.utc(moment(info.diffTime, "DD/MM/YYYY HH:mm:ss").diff(moment(CurrentTime, "DD/MM/YYYY HH:mm:ss"))).format("HH:mm:ss");
info.finalCountDown= TotalHours;
};
The issue here is the following:
Case 1:
endTime = 9/15/2016 9:16:00 AM
currentTime = 9/15/2016 1:21:00 PM
TotalHours = 4:05:00
But... if its after next 2 days...
Case 2:
endTime = 9/17/2016 9:16:00 AM
currentTime = 9/15/2016 1:21:00 PM
TotalHours = 4:05:00
Total hours is still the same...
I need it to add 24hours + 24 hours + extra time = 48 + 4:05:00 = 52:05:00
also I want it to display as: 52h:05m:00s
Please let me know how to solve this...
A quick and dirty solution would be to simply convert the difference between the two date/time objects to milliseconds and then do some math on the milliseconds and format the output as follows:
var currentTime = new Date("9-15-2016 13:21:00");
var endTime = new Date("9-17-2016 09:16:00");
var ms = (endTime - currentTime); // ms of difference
var days = Math.round(ms/ 86400000);
var hrs = Math.round((ms% 86400000) / 3600000);
var mins = Math.round(((ms% 86400000) % 3600000) / 60000);
$scope.finalCountdown = (days + "d:" + hrs + " h:" + mins + "m left");
You could add in a calculation for the seconds if you needed and you can do some formatting of the numbers to have leading zeros.
However, doing this doesn't account for issues such as leap-years and other data and time anomalies. A better suggestion would be to use angular-moment which utilizes Moment.js as it can handle differences and formatting with ease.

"Week of the year" Algorithm needs improvements

I have an algorithm which scans through data read from a .csv file(approx 3700 lines) and assess's which trading week of the year each entry is in by running a count++ for every Sunday of that year and assigning the count value as the trading week when the date falls within that week.
It's working but performance is lagging. It is the 3rd function running using Task.Factory.StartNew (I have also tried parallel.Invoke).
Results of timing tests.
before: 00:00:05.58
after: 00:00:23.27
UPDATE
Added break after each trading week is set. Time improved but still slow.
new time: 00:00:15.74
For our purposes the 1st week of the year is week 1(not 0) and is defined as from the first day of the year until the Sunday. If the first day of the year is a Sunday the length of week 1 is 1 day.
private void SetDefiniteWeeks()
{
string FileLoc = FilePath + Market + ".csv";
string[] Data = File.ReadAllLines(FileLoc);
var FileData = from D in Data
let DataSplit = D.Split(',')
select new
{
Date = DateTime.Parse(DataSplit[0]),
ClosingPrice = double.Parse(DataSplit[4])
};
//assign each date to it's relevant week
TradingWeek TW;
List<TradingWeek> tradingWeek = new List<TradingWeek>();
foreach (var pe in FileData)
{
// DateTime dt = pe.Date;
int Year = pe.Date.Year;
string End_of_Week = "Sunday";
int WeekCount = 0;
DateTime LoopDate_Begin = new DateTime(Year,1,1);
DateTime LoopDate_End = new DateTime(Year,12,31);
do
{
if (LoopDate_Begin.DayOfWeek.ToString() == End_of_Week)
{
WeekCount++;
if (LoopDate_Begin.DayOfYear > pe.Date.DayOfYear && LoopDate_Begin.DayOfYear < (pe.Date.DayOfYear + 7))
{
TW = new TradingWeek { Week = WeekCount, Date = pe.Date };
tradingWeek.Add(TW);
break;
}
}
LoopDate_Begin = LoopDate_Begin.AddDays(1);
} while (LoopDate_Begin.Date.ToString() != LoopDate_End.Date.ToString());
}
}
Please help.
UPDATE
NEW TIME
00:00:06.686
A vast improvement. Thanks all for your help.
Revised code:
CalendarWeekRule cw = CalendarWeekRule.FirstDay;
var calendar = CultureInfo.CurrentCulture.Calendar;
var trad_Week = (from pe in FileData
select new TradingWeek
{
Date = pe.Date,
Week = (calendar.GetWeekOfYear(pe.Date, cw,DayOfWeek.Sunday))
}).ToList();
Im not sure if this is what you want but after reading the comments I got the feeling that this might work (?)
var calendar = CultureInfo.CurrentCulture.Calendar;
var tradingWeek = (from pe in FileData
select new TradingWeek
{
Date = pe.Date,
Week = calendar.GetWeekOfYear(pe.Date, CalendarWeekRule.FirstDay, DayOfWeek.Sunday);
}).ToList();
Edit: Changed to CalendarWeekRule.FirstDay since it's (more?) what OP is looking for.
Three quick thoughts:
Why are you only adding one day each time and checking to see if it's Sunday. Surely once you have found your first Sunday you can add seven days to find the next one?
If you order your pes by DateTime before you start then you don't need to restart at the beginning of the year for each one, you can pick up where you left off.
As Nicolas says, break after adding the trading week. No need to go through the rest of the year after you already know what the answer is.
I guess you'll end up with something like this (may or may not actually work, but should be close enough)
TradingWeek TW;
List<TradingWeek> tradingWeek = new List<TradingWeek>();
string End_of_Week = "Sunday";
var orderedData = FileData.OrderBy(x => x.Date)
DateTime LoopDate_Begin = new DateTime(orderedData[0].Date.Year,1,1);
int WeekCount = 1;
while (LoopDate_Begin.DayOfWeek.ToString() != End_of_Week)
{
LoopDate_Begin = LoopDate_Begin.AddDays(1);
}
foreach (var pe in orderedData)
{
do
{
if (LoopDate_Begin.DayOfYear > pe.Date.DayOfYear && LoopDate_Begin.DayOfYear < (pe.Date.DayOfYear + 7))
{
TW = new TradingWeek { Week = WeekCount, Date = pe.Date };
tradingWeek.Add(TW);
break;
}
WeekCount++;
LoopDate_Begin = LoopDate_Begin.AddDays(7);
} while (true); //need to be careful here
}
if I get you correctly, you don't need to look any further as soon as you've added your TradingWeek
So, you can
break;
after
tradingWeek.Add(TW);
You could then even leave out the
&& LoopDate_Begin.DayOfYear < (pe.Date.DayOfYear + 7)
condition since the first part is going to be true only once: for your desired interval.
You might even go for a loopless approach by dividing the number of days since your starting week by 7 - and doing some cleaning up work ;)
Can you get rid of your do loop altogether by calculating the Week Number directly? Something like the accepted answer here.
Following #nicolas78's response, something like this should work
int Year = pe.Date.Year;
DateTime Year_Begin = new DateTime(Year,1,1);
int Jan1DayOfWeek = Year_Begin.DayOfWeek;
foreach (var pe in FileData)
{
int WeekCount = (pe.Date.DayOfYear - Jan1DayOfWeek) % 7 + 1;
TradingWeek TW = new TradingWeek { Week = WeekCount, Date = pe.Date };
tradingWeek.Add(TW);
}
Depending on how DayOfWeek and DayOfYear count, that is from 0 or 1, and how your mod operation work, you may need to tweak the WeekCount computation a bit.
There's a built-in feature to get the week of the year based on the date in .NET. An example is shown below, but it may need some tweaking to fit your business scenario:
System.Globalization.CultureInfo myCI = new System.Globalization.CultureInfo("en-US");
int week = myCI.Calendar.GetWeekOfYear(DateTime.Now.ToUniversalTime(), System.Globalization.CalendarWeekRule.FirstFourDayWeek, System.DayOfWeek.Sunday);
You don't need to count at all - just do a quick calculation. This assumes that a partial week at the start of the year is week 1 and week 2 begins on the first Monday.
List<TradingWeek> tradingWeek = new List<TradingWeek>();
foreach (var pe in FileData)
{
var date = pe.Date;
while (date.DayOfWeek != DayOfWeek.Sunday)
date = date.AddDays(1);
var week = date.DayOfYear/7+1;
var TW = new TradingWeek {Week = week, Date = pe.Date};
tradingWeek.Add(TW);
}

Resources