I looking for a way to output how old something is for some reporting. I'm pretty open to approach, libraries, packages, and languages. Though bash, golang, and python would be preferred. I have already researched many different ways to do this. Though I keep seeing the same results which is not my ideal output. The outputs I am seeing are something like 45 days ago, or 1.06 months ago.
I'm looking for a way to output hours, days, weeks, months, and years. And example of this output would be "Last ran: 1 month, 2 weeks, 4 days, and 9 hours ago". Right now I'm currently getting the dates as epoch timestamps from bash date tool. So I can do any kind of conversion necessary to input. For sake of example here are some inputs: 2020-03-19T05:12:14, 2019-08-27T08:47:27, 2020-05-12T11:10:18, 2020-02-01T07:40:01. I'm trying to get how old these time stamps are from current time/date. So essentially what date outputs. Or other language equivalent.
More examples to demonstrate what I don't want echo $(( ($(date +%s) - $(date -d "2020-08-27T05:47:27" +%s) )/(60*60*24) )) => 16 Instead I want 2 weeks and 2 days. Same for something over a month or year old. Hours is the smallest increment that I really care about.
Related
I initially learned that Unix time is the number of seconds that have elapsed since 00:00:00 (UTC) on 1 January 1970. With 24 hours in a day, that means that the unix timestamp grows by 86400 every day.
Then I heard about the concept of leap seconds, and thought that would mean that maybe on some days, the unix timestamp would grow by 86401 seconds in a day, but apparently this is not the case. From what I've read, every day is treated as if it contains exactly 86400 seconds. When you get a leap second, the operating system will 'fudge' it in some way to make sure there's still 86400 timestamps - either make every 'second' that day a little bit longer than a real SI second, or they'll report the same integer timestamp twice in a row.
So I think that this means that every date since 1 Jan 1970 can be mapped to a unique integer which is the timestamp at 00:00:00 (UTC) that day divided by 86400. (guaranteed to be an integer with no remainder because as discussed every day has to have 86400 timestamps). Alternatively you could take any timestamp during that day and calculate floor(timestamp / 86400).
For example, today, Fri 23rd April 2021 - timestamp at 00:00:00 UTC was 1619136000.
As expected, this is a multiple of 86400, and 1619136000 / 86400 = 18740.
There have been 18740 days since the unix epoch.
So my question is:
Does this integer already have a well-known name? Is it already widely used in software for representing dates? I've not been able to find any reference online to this concept.
Is my logic here correct - is there really a unique integer for each date, and you can easily calculate it in your code as timestamp_at_midnight_utc / 86400? Or is there some subtle problem that I've overlooked.
My motivation here is that I often have to do complicated calculations involving lots of dates without any time information (I work for a vacation rentals company where each unit has it's own availability calendar). I think I could make a lot of efficiency improvements in my code if I was working with integers uniquely representing a date, instead of DateTime objects, or strings like '2021-04-23'.
Yes, your logic is correct. Where I still get worried is that it requires you to do your calculations in UTC. Holiday rentals happen in a time zone, and associating a date in that time zone with the start of the day in UTC instead could get confusing soon.
And yes, the concept of a count of days since 1970-01-01 is sometimes used, though not often that I have seen.
In the Java documentation the terms “epoch day” and “epoch day count” are used, but this doesn’t make these terms a standard.
I think that the first avenue for you to consider is whether either your programming language comes with a library for counting days without the need to convert to and from seconds, or there is a trustworthy third-party library that you may use for the purpose.
This Java snippet confirms your calculation:
// A LocalDate in Java is a date without time zone or UTC offset
LocalDate date = LocalDate.of(2021, Month.APRIL, 23);
long epochDayCount = date.toEpochDay();
System.out.println("Epoch day: " + epochDayCount);
Output agrees with the result you got:
Epoch day: 18740
Link: Epoch day count in the Java documentation.
From my experience there is no official name for "days since epoch". Some nuances that can be detected about UNIX time (and its measurement units):
It appears to be (relatively) officially defined as the number of seconds since the UNIX epoch.
The main purpose of the UNIX time mechanism (regardless of measurement unit conventions) is to define a point in time.
In the context of point #2, in practice, it has already become traditional that the UNIX timestamp is often returned in milliseconds.
There are several factors that can influence the measurement unit that is available to you:
design decisions by APIs, libraries and programming languages
time resolution / clock frequency of the software & hardware that you are running on - e.g. some circuits, controllers or other entities aren't able to reach millisecond resolution or they don't have enough bits available in memory to represent big numbers.
performance reasons - offering a time service at millisecond or second resolution via HTTP might prove too much for networks / server CPUs. The next best thing would be a UNIX timestamp in minutes. This value can then be cached by intermediary caches for the duration of 1 minute.
use cases - there are epochs (e.g. in astronomy) where the day is the main measurement unit.
Here are a few examples of such day-based epochs:
The Julian Day system - which has a non-integer Julian Date (JD) but an integer Julian Day Number (JDN). Its epoch is at noon 24 November 4714 BC.
J2000 epoch - measured via Julian Date as well. Its epoch is January 1, 2000, 11:58:55.816 UTC.
If you have a look at one method of calculating the Julian Date, dividing by 86400 is an important step. So, given that the JD system seems to be widely used in astronomy, I think it would be safe to consider this division by 86400 as valid :)
This is a more complex question than you might initially realize. You want the days since 1970 to be the same for all times during the local day, and you also don't want daylight saving time changes in the local time zone and UTC date changes to affect the output.
The solution I found was to compute the seconds since 1970 in UTC but for the current local date at midnight, not the current UTC date. Here is a Linux shell script solution:
echo $(( $(date -u -d "$(date '+%Y-%m-%d') 00:00:00" '+%s') / 24 / 60 / 60 ))
date -u forces UTC time, while the second date returns the local year-month-day. This computation actually generates an integer result, even if you use a computation that supports non-integers. Computing the seconds since 1970 in local time, or using the current UTC date (and no the local day) will not work.
I have a challenge that i'm really struggling with.
I have a table which contains a 'scenario' that a user has defined, that they will consume 'usage'. For example, how many hours a machine will be turned on for.
In month 1, they will use 300 (hours, stored as an integer in minutes), Month 2 100, Month 3 450 etc etc etc.
I then have a list of tasks which need to be performed at specific intervals of usage. Given the above scenario, how could I forecast when these tasks will be due (the date). I also need to show repeat accomplishments and the dates.
The task contains the number of consumed hours at the last point of accomplishment, the interval between accomplishments and the expected life total the next time it is due (Last Done + Interval = Next Due)
I've tried SO many different options, ideally I want this to be compiled at run time (i.e. the only things that are saved into a permanent table are the forecast and the list of tasks). I have 7-800 scenarios, plus given the number of pieces of equipment, there are 12,000 tasks to be carried out. I need to show at least the next 100 years of tasks.
At the minute, I get the scenario, cross apply a list of dates between now and the year 2118. I then (in the where clause) filter out where the period number (the month number of the year) isn't matching the date, then divide the period usage by the number of days in that period. That gives me a day to day usage over the next 100 years (~36,000 Rows) When I join on the 12000 tasks and then try to filter where the due at value matches my dates table, I can't return ANY rows, even just the date column and the query runs for 7-8 minutes.
We measure more than just hours of usage too, there are 25 different measurement points, all of which are specificed in the scenario.
I can't use linear regression, because lets say for example, we shut down over the summer, and we don't utilize the equipment, then an average usage over the year means that tasks are due, even when we are telling the scenario we're shut down.
Are there any strategies out there that I could apply. I'm not looking for a 'Here's the SQL' answer, I'm just running out of strategies to form a solid query that can deal with the volume of data I'm dealing with.
I can get a query running perfectly with one task, but it just doesn't scale... at all...
If SQL isn't the answer, then i'm open to suggestions.
Thanks,
Harry
I am trying to use below perl command to convert epoch times to readable localtime:
bash-3.2$ perl -le print\ scalar\ localtime\ 32503651200
Thu Mar 9 19:13:52 1911
Below year 2038 is possible to be converted correctly, but for year numbers is greater than 2038 I couldn't get expected result.
Please advise how to fix. Thanks.
The year 2038 bug on 32 bit systems was worked around in Perl 5.12.0 (64 bit systems are unaffected by the 2038 bug). I know because I did it (with help). :) Simply upgrade your Perl and the problem (and a lot of others) is solved.
Alternatively, use a date library such as DateTime. It does not rely on system time functions (the root of the 2038 bug), is unaffected by the y2038 bug, and is generally much, much easier to use.
If you can't upgrade Perl and must use localtime and gmtime, you can use Time::y2038 to get versions of those functions unaffected by the 2038 bug.
Year 2038 problem
The Year 2038 problem is an issue for computing and data storage situations in which time values are stored or calculated as a signed 32-bit integer, and this number is interpreted as the number of seconds since 00:00:00 UTC on 1 January 1970 ("the epoch").1 Such implementations cannot encode times after 03:14:07 UTC on 19 January 2038, a problem similar to but not entirely analogous to the "Y2K problem" (also known as the "Millennium Bug"), in which 2-digit values representing the number of years since 1900 could not encode the year 2000 or later. Most 32-bit Unix-like systems store and manipulate time in this "Unix time" format
I have query that get timestampdiff but from understanding of the function of timestampdiff that it have assumption of 30 days a month so my question is there a way to make it more accurate or way to make it more accurate to consider the timing in months that have less than 30 days or more than 30 days to get the accurate results, i been searching for information on this but wouldn't able to find any, any one got into that more.
Thanks!!
I am really having a heck of a time figuring out which way I should do this. Been coding objective-c for 4 months now, well trying to at least.
I have about 100+ different dates spanning 2012, down to the second, in multiple timezones. What I need is:
to grab the present time/date, see which 2 dates in my 100+ list it is between and give me time spent and time remaining.
to know which 2 dates it is between no matter what timezone a user is in.
all calculations need to take in consideration of daylight savings time. Which the dates and times of DST change is different depending on the timezone and country.
a user in Hawaii will have the same time remaining and spent as a user in England.
ablility to convert all times to local user time.
have this all realtime. have the clock or timer counting down to the second.
I have tried NSDate. Then I searched this site and found NSDateFormatter. I played with that for what seems like days. Then another search I found NSDateComponents. Do I put my 100+ dates in a multidimensional array. Do I convert everything to GMT first or can xcode do that for me. Or do I convert everytime to seconds since 1970. I am just lost on what would be the best most practical way of doing this.
Any help, thanks so much!!
I am not an iOS programmer, but if you could convert everything to the same time zone (MST, EST, GMT, whatever), then that would make your job far easier. Converting between time zones runs in constant time as there is nothing more involved than simple addition/subtraction.
As for DST, if you convert to MST or EST (as opposed to MDT or EDT), you inherently remove DST. What exactly do you mean by "take in consideration of DST?" I could help much more if you could provide that.