Calculating time in ASP.NET [duplicate] - asp.net

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
How do I calculate relative time?
While posting something on SO it shows posted 5 mins ago or 1hr ago. How do I calculate the time and display it the same way?

For example C# Pretty Date Formatting:
static string GetPrettyDate(DateTime d)
{
// 1.
// Get time span elapsed since the date.
TimeSpan s = DateTime.Now.Subtract(d);
// 2.
// Get total number of days elapsed.
int dayDiff = (int)s.TotalDays;
// 3.
// Get total number of seconds elapsed.
int secDiff = (int)s.TotalSeconds;
// 4.
// Don't allow out of range values.
if (dayDiff < 0 || dayDiff >= 31)
{
return null;
}
// 5.
// Handle same-day times.
if (dayDiff == 0)
{
// A.
// Less than one minute ago.
if (secDiff < 60)
{
return "just now";
}
// B.
// Less than 2 minutes ago.
if (secDiff < 120)
{
return "1 minute ago";
}
// C.
// Less than one hour ago.
if (secDiff < 3600)
{
return string.Format("{0} minutes ago",
Math.Floor((double)secDiff / 60));
}
// D.
// Less than 2 hours ago.
if (secDiff < 7200)
{
return "1 hour ago";
}
// E.
// Less than one day ago.
if (secDiff < 86400)
{
return string.Format("{0} hours ago",
Math.Floor((double)secDiff / 3600));
}
}
// 6.
// Handle previous days.
if (dayDiff == 1)
{
return "yesterday";
}
if (dayDiff < 7)
{
return string.Format("{0} days ago",
dayDiff);
}
if (dayDiff < 31)
{
return string.Format("{0} weeks ago",
Math.Ceiling((double)dayDiff / 7));
}
return null;
}
(And you can also use a jquery plugin named Prettydate.)

Related

Dart/Flutter How to compare two TimeOfDay times?

TimeOfDay documentation has no comparison operator and primitive comparison does not work. My only solution that I can thinking of right now is to convert TimeOfDay to DateTime and use DateTime's difference method.
Does anyone have a better solution?
Convert it to a double then compare.
double toDouble(TimeOfDay myTime) => myTime.hour + myTime.minute/60.0
extension TimeOfDayExtension on TimeOfDay {
int compareTo(TimeOfDay other) {
if (hour < other.hour) return -1;
if (hour > other.hour) return 1;
if (minute < other.minute) return -1;
if (minute > other.minute) return 1;
return 0;
}
}
Thanks from #Lucas idea, you can calculate hour and minute by
TimeOfDay yourTime ;
TimOfDay nowTime = TimeOfDay.now()
double _doubleYourTime = yourTime.hour.toDouble() +
(yourTime.minute.toDouble() / 60);
double _doubleNowTime = nowTime.hour.toDouble() +
(nowTime.minute.toDouble() / 60);
double _timeDiff = _doubleYourTime - _doubleNowTime;
double _hr = _timeDiff.truncate();
double _minute = (_timeDiff - _timeDiff.truncate()) * 60;
print('Here your Happy $_hr Hour and also $_minute min');
I calculated the difference by turning both values into minute-counts, and comparing those :)
TimeOfDay now = TimeOfDay.now();
int nowInMinutes = now.hour * 60 + now.minute;
TimeOfDay testDate = TimeOfDay(hour: 2, minute: 20);
int testDateInMinutes = testDate.hour * 60 + testDate.minute;
You can use this method. Where you have to provide starttime and endTime in TimesofDay format.
getTime(startTime, endTime) {
bool result = false;
int startTimeInt = (startTime.hour * 60 + startTime.minute) * 60;
int EndTimeInt = (endTime.hour * 60 + endTime.minute) * 60;
int dif = EndTimeInt - startTimeInt;
if (EndTimeInt > startTimeInt) {
result = true;
} else {
result = false;
}
return result;
}
LikeThis
getTime(v1, v2);
TimeOfDay n = TimeOfDay.now();
int nowSec = (n.hour * 60 + n.minute) * 60;
int veiSec = (t.hour * 60 + t.minute) * 60;
int dif = veiSec - nowSec;
Card(
child: ListTile(
onTap: () {
showTimePicker(
context: context,
initialTime: TimeOfDay.now(),
).then((TimeOfDay time) {
double _doubleyourTime =
time.hour.toDouble() + (time.minute.toDouble() /60);
double _doubleNowTime = TimeOfDay.now().hour.toDouble() +
(TimeOfDay.now().minute.toDouble() / 60);`enter code here`
if (_doubleyourTime > _doubleNowTime) {
print('correct format')
});
} else {
print('Sorry You can not set the time')
}
});
},
//dense: true,
leading: Icon(Icons.timer),
title: Text(
'Today On Time',`enter code here`
),
),
),
We can actually use the subtract operator.
Code to make magic happen :
Here I wanted to get the difference in time after the user selects the time (in TimeOfDay format) using showTimePicker()
// current time will be used to find the difference between the time selected by the user.
TimeOfDay _cur_time = TimeOfDay(hour: DateTime.now().hour, minute: DateTime.now().minute);
// scheduled time will be updated as soon as the user inputs a new time using the showTimePicker() function available in Flutter Material librabry.
TimeOfDay _scheduled_time = TimeOfDay(hour: DateTime.now().hour, minute: DateTime.now().minute);
// toDouble Function to convert time to double so that we can compare time and check that the time selected is greater than current time.
double toDouble(TimeOfDay myTime) => myTime.hour + myTime.minute / 60.0;
void _selectTime() async {
Flutter Material widget to select time.
final TimeOfDay? newTime = await showTimePicker(
context: context,
initialTime: _scheduled_time,
);
//Check if the selected time is greater than the cur time
if (toDouble(newTime!) > toDouble(_cur_time)) {
setState(() {
_scheduled_time = newTime;
});
}
}
Function to get the difference between cur time and selected time.
Duration _getDelayedDuration(){
var hourDelay = _scheduled_time.hour - _cur_time.hour;
print(hourDelay);
var minuteDelay = _scheduled_time.minute - _cur_time.minute;
print(minuteDelay);
return Duration(hours: hourDelay, minutes: minuteDelay);
}
Solution for negative duration calculations
All these answers are pretty good but they didn't help me when I had a user select a range of times in my app. In order to calculate the total duration of the specified time period, I tried all the solutions which work pretty well but fail in certain scenarios. The scenarios are:
When the start time comes after the end time (i.e- when the duration is supposed to be over 12 hours)
When the start time is before 12am at the night and end time is after that
And the code to overcome it is:
String durationFromTimeOfDay(TimeOfDay? start, TimeOfDay? end) {
if (start == null || end == null) return '';
// DateTime(year, month, day, hour, minute)
final startDT = DateTime(9, 9, 9, start.hour, start.minute);
final endDT = DateTime(9, 9, 10, end.hour, end.minute);
final range = DateTimeRange(start: startDT, end: endDT);
final hours = range.duration.inHours % 24;
final minutes = range.duration.inMinutes % 60;
final _onlyHours = minutes == 0;
final _onlyMinutes = hours == 0;
final hourText = _onlyMinutes
? ''
: '$hours${_onlyHours ? hours > 1 ? ' hours' : ' hour' : 'h'}';
final minutesText = _onlyHours
? ''
: '$minutes${_onlyMinutes ? minutes > 1 ? ' mins' : ' min' : 'm'}';
return hourText + minutesText;
}
It is important to note that you need to prefill the DateTime for end TimeOfDay with a day value which is greater than the same in start DateTime. The other parameters (for year and month) can be anything you want.
This outputs a really nicely formatted string that is short, concise, and extremely legible
This, however, doesn't satisfy the requirement that the solution is devoid of conversion to DateTime. But at least it uses a different approach over the difference method. And this makes the correct duration calculation more reliable in a few lines of code comparatively.
I don't think this is possible. You can use .subtract in DateTime as also .difference

calculating time differences using moment.js

Friends,
I have an array containing checkins and checkouts times and need to calculate the spent time between these operations. For that I iterate through this table partitioning checkins from checkouts in two separated arrays, like that:
var checkins = [];
var checkouts = [];
var results = [];
var index;
for (index = 0; index < $scope.data.registries.length; ++index){
if ($scope.data.registries[index].rType == 0) {
checkins.push(moment($scope.data.registries[index].savedHour, "HH:mm:ss"));
}
else {
checkouts.push(moment($scope.data.registries[index].savedHour, "HH:mm:ss"));
}
}
After that I just iterate over checkins array, calculating the diffs and pushing it into the results array, like this:
for (index = 0; index < checkins.length; ++index){
if (index <= checkouts.length) {
results.push(moment.utc(checkouts[index]).diff(moment(checkins[index])));
}
}
So, now I have an array containing only the diff times, for each pair of checkin checkout. Now I just
make a sum of theses diffs... like this:
var total = null;
for (index = 0; index < results.length; ++index) {
if (index == 0){
total = moment(results[index]);
}
else{
total.add(results[index]);
}
}
if (results.length == 0) {
return "00 hour(s) and 00 minute(s)";
}
else {
return moment.utc(total).format("HH [ hour(s) and ] mm [ minute(s)]");
}
I'm not getting the correct amount of time.... for the following sample data:
checkin 07:32
checkout 07:34 ->
difference: 2 minutes
checkin 08:20
checkout 08:53 ->
difference: 33 minutes
I should have a total of 35 minutes, but
its always changing according to current time... for example, here now is 10:51 (am)
and this function is returning 2h and 37m
I dont see what is wrong... could someone point it out?
A few things:
You're subtracting UTC against local time:
moment.utc(checkouts[index]).diff(moment(checkins[index]))
^^^^^^^^^^ ^^^^^^
Either both values should be UTC, or both values should be local.
You said your inputs were time-only values. Keep in mind that when you don't specify a date, the current date is assumed. If you are working with local times on a day that has a daylight saving time transition, you may get results that are adjusted by up to an hour. If you intend to work with the current day and want accurate elapsed times, then this should be expected. Otherwise, you'll want to fix the time to a particular date.
You aren't considering time ranges that cross midnight, for example 22:00 to 02:00 should be 4 hours (on most days). You should check if the values are in sequence, and add a day to the checkout value if not.
I did a short example in my Chrome console and got the correct answer with the following:
var start = moment('07:32', "HH:mm:ss")
var stop = moment('07:34', "HH:mm:ss")
var diff1 = moment.utc(stop).diff(moment(start))
start = moment("08:03", "HH:mm:ss")
stop = moment("08:33", "HH:mm:ss")
var diff2 = moment.utc(stop).diff(moment(start))
var total = moment(diff1)
total.add(diff2)
moment.utc(total).format("HH [ hour(s) and ] mm [ minute(s)]");
"00 hour(s) and 32 minute(s)"
So looks like your logic is correct without the arrays and for loops.
Friends... logic problems in my loops hehehheh
I was using
for (index = 0; index < checkins.length; ++index){
if (index <= checkouts.length) {
results.push(moment.utc(checkouts[index]).diff(moment(checkins[index])));
}
}
the correct is
for (index = 0; index < checkins.length; ++index){
if (index <= checkouts.length-1) {
results.push(moment.utc(checkouts[index]).diff(moment(checkins[index])));
}
}

Full humanized durations in moment.js

I tried this in moment.js
moment.duration(375,'days').humanize()
and get "a year" as answer, but I would expect "a year and 10 days". Is there a way in moment.js to get the full humanized value?
Moment.js is providing the fromNow function to get time durations in human readable fromat, see http://momentjs.com/docs/#/displaying/fromnow/
Example:
moment([2007, 0, 29]).fromNow(); // 4 years ago
moment().subtract(375, 'days').fromNow(); // a year ago
You need to use third party lib as suggested by #Fluffy
I found this small lib, that only display duration (if you don't really need all the features of moment.js)
https://github.com/EvanHahn/HumanizeDuration.js
Try this plugin:
https://github.com/jsmreese/moment-duration-format
moment.duration(123, "minutes").format("h [hrs], m [min]");
// "2 hrs, 3 min"
I was looking at the same issue and seems like there is no plan on supporting this in the future...
Although one workaround proposed is to make an language definition that overrides default implementation of humanized messages:
https://github.com/timrwood/moment/issues/348
Kind of an overkill if you ask me...
Use moment.relativeTimeThreshold('y', 365) to set the rounding.
moment.relativeTimeThreshold('s', 60);
moment.relativeTimeThreshold('m', 60);
moment.relativeTimeThreshold('h', 24);
moment.relativeTimeThreshold('d', 31);
moment.relativeTimeThreshold('M', 12);
moment.relativeTimeThreshold('y', 365);
I made a function to solve this exact problem.
function formatDuration(period) {
let parts = [];
const duration = moment.duration(period);
// return nothing when the duration is falsy or not correctly parsed (P0D)
if(!duration || duration.toISOString() === "P0D") return;
if(duration.years() >= 1) {
const years = Math.floor(duration.years());
parts.push(years+" "+(years > 1 ? "years" : "year"));
}
if(duration.months() >= 1) {
const months = Math.floor(duration.months());
parts.push(months+" "+(months > 1 ? "months" : "month"));
}
if(duration.days() >= 1) {
const days = Math.floor(duration.days());
parts.push(days+" "+(days > 1 ? "days" : "day"));
}
if(duration.hours() >= 1) {
const hours = Math.floor(duration.hours());
parts.push(hours+" "+(hours > 1 ? "hours" : "hour"));
}
if(duration.minutes() >= 1) {
const minutes = Math.floor(duration.minutes());
parts.push(minutes+" "+(minutes > 1 ? "minutes" : "minute"));
}
if(duration.seconds() >= 1) {
const seconds = Math.floor(duration.seconds());
parts.push(seconds+" "+(seconds > 1 ? "seconds" : "second"));
}
return "in "+parts.join(", ");
}
This function takes a period string (ISO 8601), parses it with Moment (>2.3.0) and then, for every unit of time, pushes a string in the parts array. Then everything inside the parts array gets joined together with ", " as separation string.
You can test it here: https://jsfiddle.net/mvcha2xp/6/
I'm using it as a Vue filter to humanize durations correctly.
This issue on Github contains a lot of discussion about exactly that. Many are asking for a more precise humanized option.
Chime in with why you need it, use cases, etc.
https://github.com/moment/moment/issues/348
i have written this javascript code to humanize the duration,
function humanizeDuration(timeInMillisecond) {
var result = "";
if (timeInMillisecond) {
if ((result = Math.round(timeInMillisecond / (1000 * 60 * 60 * 24 * 30 * 12))) > 0) {//year
result = result === 1 ? result + " Year" : result + " Years";
} else if ((result = Math.round(timeInMillisecond / (1000 * 60 * 60 * 24 * 30))) > 0) {//months
result = result === 1 ? result + " Month" : result + " Months";
} else if ((result = Math.round(timeInMillisecond / (1000 * 60 * 60 * 24))) > 0) {//days
result = result === 1 ? result + " Day" : result + " Days";
} else if ((result = Math.round(timeInMillisecond / (1000 * 60 * 60))) > 0) {//Hours
result = result === 1 ? result + " Hours" : result + " Hours";
} else if ((result = Math.round(timeInMillisecond / (1000 * 60))) > 0) {//minute
result = result === 1 ? result + " Minute" : result + " Minutes";
} else if ((result = Math.round(timeInMillisecond / 1000)) > 0) {//second
result = result === 1 ? result + " Second" : result + " Seconds";
} else {
result = timeInMillisecond + " Millisec";
}
}
return result;
}
One of the solutions:
function getCountdown() {
// diff in seconds, comes through function's params
const diff = 60*60*24*4 + 60*60*22 + 60*35 + 5;
const MINUTE = 60;
const HOUR = MINUTE * 60;
const DAY = HOUR * 24;
const days = Math.floor(diff / DAY);
const hDiff = diff % DAY;
const hours = Math.floor(hDiff / HOUR);
const mDiff = hDiff % HOUR;
const minutes = Math.floor(mDiff / MINUTE);
const seconds = mDiff % MINUTE;
return [days, hours, minutes, seconds]
.map(v => (''+v)[1] ? ''+v : '0'+v)
}
output: ["04", "22", "35", "05"]
I needed it up to days only, but can be easily extended to weeks.
Doesn't make sense with months since diff says nothing about start date.
Having a period split to parts, adding "days"/"hours"/... is obvious.
Moment.js provides:
var y = moment.duration(375,'days').years(); // returns 1
var d = moment.duration(375,'days').days(); // returns 9
var data = y + 'y ' + d + 'd';
console.log(data);
This could be used with a bit of extra logic
This is my solution on CoffeeScript:
humanizeDuration = (eventDuration)->
eventMDuration = Moment.duration(eventDuration, 'seconds');
eventDurationString = ""
if (eventMDuration.days() > 0)
eventDurationString += " " + Moment.duration(eventMDuration.days(), 'days').humanize()
if (eventMDuration.hours() > 0)
eventDurationString += " " + Moment.duration(eventMDuration.hours(), 'hours').humanize()
if (eventMDuration.minutes() > 0)
eventDurationString += " " + Moment.duration(eventMDuration.minutes(), 'minutes').humanize()
eventDurationString.trim()
This is my solution, I like it better than the others here:
val moment1 = moment();
val moment2 = mement();
console.log(moment.duration(moment1.diff(moment2)).humanize());
Based on Ihor Kaslashnikov's solution, I modified the function to be even more accurate using vanilla Javascript.
function momentHumanize(eventDuration, unit) {
var eventMDuration = moment.duration(eventDuration, unit);
var eventDurationArray = [];
if (eventMDuration.years() > 0) {
eventDurationArray.push(eventMDuration.years() + ' years');
eventMDuration.subtract(eventMDuration.years(), 'years')
}
if (eventMDuration.months() > 0) {
eventDurationArray.push(eventMDuration.months() + ' months');
eventMDuration.subtract(eventMDuration.months(), 'months')
}
if (eventMDuration.weeks() > 0) {
eventDurationArray.push(eventMDuration.weeks() + ' weeks');
eventMDuration.subtract(eventMDuration.weeks(), 'weeks')
}
if (eventMDuration.days() > 0) {
eventDurationArray.push(eventMDuration.days() + ' days');
eventMDuration.subtract(eventMDuration.days(), 'days')
}
if (eventMDuration.hours() > 0) {
eventDurationArray.push(eventMDuration.hours() + ' hours');
eventMDuration.subtract(eventMDuration.hours(), 'hours')
}
if (eventMDuration.minutes() > 0) {
eventDurationArray.push(eventMDuration.minutes() + ' minutes');
}
return eventDurationArray.length === 1 ? eventDurationArray[0] :
eventDurationArray.join(' and ')
}
This will remove any amount from the moment instance once it humanizes it.
I did this because Ihor's solution was inaccurate, given that moment's humanize function rounds the value. For example, if I had 2.8 hours, it should've been 2 hours and an hour.
My solution removes the 2 hours, from the instance, leaving only 0.8 hours, and doesn't use moment's humanize function to avoid rounding.
Examples:
momentHumanize(45, 'minutes') // 45 minutes
momentHumanize(4514, 'minutes') // 3 days and 3 hours and 14 minutes
momentHumanize(45145587, 'minutes') // 85 years and 10 months and 1 days and 2 hours and 27 minutes
var s=moment([2020, 03, 29]).subtract(3, 'days').fromNow();
document.write(s)
enter link description here

Can this date time function be written more efficiently?

The following function returns the difference between two date time values in words (as a string). Can it be written more efficiently/elegantly?
/**
* #hint Returns the difference between two time strings in words.
*/
public string function timeAgoInWords(required date fromTime, date toTime=now())
{
local.secondDiff = dateDiff("s", arguments.fromTime, arguments.toTime);
if (local.secondDiff <= 60)
return "#local.secondDiff# seconds ago";
local.minuteDiff = dateDiff("n", arguments.fromTime, arguments.toTime);
if (local.minuteDiff <= 60)
if (local.minuteDiff < 2)
return "1 minute ago";
else return "#local.minuteDiff# minutes ago";
if (local.minuteDiff <= 1440)
if (local.minuteDiff <= 120)
return "1 hour ago";
else return "#int(local.minuteDiff/60)# hours ago";
if (local.minuteDiff <= 2880)
return "yesterday";
if (local.minuteDiff <= 4320)
return "2 days ago";
local.monthDiff = dateDiff("m", arguments.fromTime, arguments.toTime);
if (local.monthDiff <= 12)
return "#dateFormat(arguments.fromTime, "mmm dd")# at #timeFormat(arguments.fromTime, "h:mm")#";
return "#dateFormat(arguments.fromTime, "mmm dd 'yy")# at #timeFormat(arguments.fromTime, "h:mm")#";
}
This is what I wrote a few months ago, based on the UDF Al Everett posted above in the comment and written in CF9 script style. It won't be more efficient. In fact, it should be slower then your implementation 'cause it has multiple calls to dateDiff(), and needs to set up 2 arrays up front, but the overall line count is shorter and easily understandable.
string function ago(required Date dateThen)
{
var dateparts = ["yyyy","m","d","h","n"];
var datepartNames = ["year","month","day","hour","minute"];
var rightNow = Now();
for (var i = 1; i <= 5; i++) // 5 == arrayLen(dateparts)
{
var diff = dateDiff(variables.dateparts[i], dateThen, rightNow);
if (diff > 1)
return "#diff# #datepartNames[i]#s ago";
if (diff == 1)
return "#diff# #datepartNames[i]# ago";
}
return "Just Now";
}
It looks good to me. You could instead use your first diff (local.secondDiff) for all your tests rather than re-diffing, but this is probably easier to read.

How do I get browser timezone using Flex/AS3?

How do I get client browser's timezone in Flex/AS3?
Have a look on the following: http://thanksmister.com/2011/10/06/determining-local-timezone-in-actionscript-air-flex-as3/
It may help.
Can you use the timeZoneOffest of the Date object?
Honestly, I believe this just passes back information based on the user's OS settings. I wouldn't have expected a bBrowser to actually have a time zone.
I've been wanting the same thing, but I found nothing on the Internet. I was already using FlexDateUtils (blog post), but it only formats timezones as 'GMT -600'. Luckily, I can safely say that the users of my app will be in the United States, so I modified to 'DateUtils.buildTimeZoneDesignation(date:Date)' as follows. I hope this helps.
private static function buildTimeZoneDesignation( date:Date ):String {
if ( !date ) {
return "";
}
var timezoneOffsetHours:Number = date.getTimezoneOffset() / 60;
// custom timezone handlers (assumes major U.S. zones with daylight savings time dates as of 2011)
if (3 < timezoneOffsetHours && timezoneOffsetHours < 12)
{
var usDST:Boolean = false;
// the date of the Sunday before today unless today is Sunday
var sundayBeforeToday:Number = date.date - date.day;
if (2007 <= date.fullYear) {
// test for since-2007 extended daylight savings time
if (2 < date.month && date.month < 10) {
// daylight savings time (April through October)
usDST = true;
}
else if (date.month == 2) {
// DST starts second Sunday in March
usDST = (7 < sundayBeforeToday);
}
else if (date.month == 10) {
// DST ends first Sunday in November
usDST = (0 < sundayBeforeToday);
}
}
else {
// test for pre-2007 daylight savings time
if (3 < date.month && date.month < 9) {
// daylight savings time (May through September)
usDST = true;
}
else if (date.month == 3) {
// DST starts first Sunday in April
usDST = (0 < sundayBeforeToday);
}
else if (date.month == 9) {
// DST ends last Sunday in October
usDST = (sundayBeforeToday + 7 <= 31);
}
}
// return custom timezone strings for US timezones
switch (timezoneOffsetHours) {
case 4:
// Eastern or Atlantic
return usDST ? "EDT" : "AST";
case 5:
// Central or Eastern
return usDST ? "CDT" : "EST";
case 6:
// Mountain or Central
return usDST ? "MDT" : "CST";
case 7:
// Pacific or Mountain
return usDST ? "PDT" : "MST";
case 8:
// Alaska or Pacific
return usDST ? "AKDT" : "PST";
case 9:
// Hawaii or Alaska
return usDST ? "HADT" : "AKST";
case 10:
// Samoa or Hawaii
return usDST ? "SDT" : "HAST";
case 11:
if (!usDST)
// Samoa
return "SST";
break;
}
}
// else just generate a GMT string
var timeZoneAsString:String = "GMT ";
// timezoneoffset is the number that needs to be added to the local time to get to GMT, so
// a positive number would actually be GMT -X hours
if ( 0 < timezoneOffsetHours && timezoneOffsetHours < 10 ) {
timeZoneAsString += "-0" + ( timezoneOffsetHours ).toString();
} else if ( date.getTimezoneOffset() < 0 && timezoneOffsetHours > -10 ) {
timeZoneAsString += "0" + ( -1 * timezoneOffsetHours ).toString();
}
// add zeros to match standard format
timeZoneAsString += "00";
return timeZoneAsString;
}

Resources