Is any math can sort out date from time-milli? (eg:1544901911)
It is possible to get time by a initial modulus of 86400 and dividing 3600 (hour) and modulus by 3600 and dividing by 60 (minute) of overal milli.
Is it possible to get date from these, I really don't know how it works (just knows that it begined from 1970 Jan 1 onwards).
Not using any code language, I am just asking the mathematics behind this.
I have problems making sense of what you wrote. 86400 is the number of seconds in a day. So if you have the time in seconds, and want the time of the day, then modulo 86400 makes sense. As your question starts with time in milliseconds, modulo 86400000 would be more appropriate. But I guess we get the idea either way.
So as I said, extracting the time of the day works as you know the number of seconds in a day. The number of seconds in a year is harder, as you have to deal with leap days. You can have a look at existing standard library implementations, e.g. Python datetime. That starts by taking the time (or rather number of days, i.e. time divided by time per day, whatever the unit) modulo 400 years, since the number of whole days in 400 years is fixed. Then it goes on looking at 100 year cycles, 4 year cycles and years, with case distinctions for leap years, and tables containing information about month lengths, and so on. Yes, this can be done, but it's tedious plus already part of standard libraries for most languages.
Related
I have at my disposal 16 bits. Of them, 4 bits are the header and cannot be touched. This leaves us with 12 bits. I would like to encode date and time data into them. These are essentially logs being sent over LPWAN.
Obviously, it's impossible to encode proper generic date and time into it. Since the unix timestamp uses 32 bits, and projects like Compact Time Format use 5 bytes.
Let's say we don't really need the year, because this information is available elsewhere. Let's also say the time resolution of seconds doesn't have to be super accurate, so we can split the seconds into 30 second intervals. If we were to simply encode the data as is then:
4 bits month (0-11)
5 bits day (0-31)
5 bits hour (0-23)
6 bits minute (0-59)
1 bit second (0,30)
-----------------------------
21 bits
21 bits is much better than 32. But it's still not 12. I could subtract one bit from the minutes (rounding to the nearest even minute), and remove the seconds but that still leaves us with 19 bits. Which is still far from 12.
Just wondering if it's possible, and if anyone has any ideas.
12 bits can hold 2^12 = 4096 values, which feels pretty tight for a task. Not sure much can be done in terms of compressing a date time into a 4096 number. It is too little space to represent this data.
There are some workarounds, none of them able to achieve what you want, but maybe something you could use anyway:
Split date and time. Alternate with some algorithm between sending date/time, one bit can be used to indicate what data is being sent. This leaves 11 bits to encode either date or time. You could go a bit further and split time like this as well. Receiving side can then reconstruct a full date time having access to the previously received data.
You could have a schema where one date packet is sent as a starting point, and subsequent packets are incremented in N-second intervals from the start of the epoch
Remove date time from data completely, saving 12 bits, but send it periodically as a stand-alone heartbeat/datetime packet.
You could try compressing the whole data packet which could allow using more bits to represent date time and still fit into a smaller overall packet size
If data is sent at reasonable fixed intervals, you could use a circular counter of an interval of N seconds, this may work if you have few devices and you can keep track of when they start transmitting. For example a satellite was launched on XYZ date time, it send counter every 30 seconds, we received counter value of 100, to calculate date we use simple math XYZ + 30*100 seconds
No. Unless you'd be happy with representing less than a span of a day and a half. You can just count 4096 30-second intervals, and find that that will cover 34 hours and eight minutes. 4096 two-minute intervals is just four times that, or five days, 16 hours, and 32 minutes. Still a small fraction of a year.
If you can assure that the difference between successive log entries is small, then you can stuff that in 12 bits. You will need a special entry to give an initial date, and maybe you could insert such an entry when the difference betweem successive entries is too large.
#oleksii has some other good suggestions as well.
With ISO8601, is there a way to specify a repeating interval which starts at a given time for any day, and repeats over time in that day?
For example, does the following hold:
R2/T09:00:00Z/PT1H = R/2000-01-01T09:00:00/P1D + R/2000-01-01T10:00:00/P1D?
Or is the former not correct under the standard?
The motivation behind this is to run a task at 9am and 10am every day.
No, Iso 8601 cannot irregular repetitions. You would need evaluate/run both of those expressions.
Cron expressions would be a better option as it is widely supported, especially for running tasks. You can find cron expression builders on the web and a library for every language (and OS support with crontab in Unix systems). This expression would handle your use case 0 0 9,10 ? * * * and would run at 9 and 10 am of every day of every year.
Sorry for the response 2 years later.
I have a program which saves some data to an NFC tag. The NFC tag only has some bytes for memory. And because I need to save a date and time in minutes (decimal) to the tag, I need to save this in the most memory efficient way possible. For instance the decimal number 23592786 requires 36 bits, but if the decimal number is converted to a base36 value it only requires 25 bits of memory.
Number 23592786 requires 25 bits, because binary representation of this number is 25-bit length. You can save some bits, if date range is limited. One year contains about 526000 minutes, so interval in minutes from 0:00 1st Jan 2000 (arbitrary start date) will take 24 bits (3 bytes) and represents dates till 2031 year.
The simplest might be to use a Unix time this gives the the number of seconds since Jan 1 1970, this typically takes 32 bits. As MBo has said you can reduce the number of bits by 6, by jut counting minutes or by choosing a more recent start date. However there are advantages in using an industry standard. Depending on you application you might be able to get it down to 2 byte which could represent about 45 days.
In other words, I'm looking for the equivalent of Python's datetime.utcnow().
I'm also fine with a n-tuple containing years, months and so on, up until milliseconds (or microseconds).
I had thought of using show and then parsing the String value, but I believe there's something more convenient.
Re-parsing a string is very un-Haskellish, you certainly don't want that.
I'd use, from Data.Time.LocalTime,
todSec . localTimeOfDay . utcToLocalTime utc :: UTCTime -> Data.Fixed.Pico
that gives you seconds in picosecond-resolution.
Seconds and milliseconds since when? Presumably there is an epoch (time zero) hiding somewhere here. You subtract the epoch from the UTCTime to get a NominalDiffTime, and then extract the seconds and milliseconds from that.
secondsSince :: UTCTime -> UTCTime -> (Integer, Int)
secondsSince t0 t1 = (i, round $ d * 1000)
where (i, d) = properFraction $ diffUTCTime t1 t0
Of course you probably want t0 to be 1/1/1970 (the Unix epoch), in which case you import Data.Time.Clock.POSIX and use utcTimeToPOSIXSeconds, which returns a NominalDiffTime.
NominalDiffTime is an instance of (amongst other things) Fractional and Num, so you have access to all the usual numeric operators when manipulating them. From an arithmetical point of view (including conversions) it is treated as a number of seconds.
When using this, do bear in mind that Unix gets time fundamentally wrong because it doesn't have any room for leap seconds. Every few years there is a day with 86401 seconds instead of the usual 86400. Back in the 70s the idea of a computer needing to know about this would have seemed absurd (clocks were generally set by the sysadmin consulting his mechanical watch), so the Unix time_t simply counts seconds since the epoch and assumes that every day has exactly 86400 seconds. NominalDiffTime is "nominal" because it makes the same assumption.
The Right Thing would have been to make time_t a struct with a day number and seconds since midnight as separate fields, and have the time arithmetic functions consult a table of leap seconds. However that would have its own set of disadvantages because new leap seconds get designated every so often, so a program could give different results when run at different times. Or to put it in Haskell terms, "diffUTCTime" would have to return a result in the IO monad.
"Geolocation is the identification of the real-world geographic location of an object. Geolocation may refer to the practice of assessing the location, or to the actual assessed location." -- http://en.wikipedia.org/wiki/Geolocation
Is there a standard way to describe temporal locations/coordinates that extend beyond Unix timestamps? If not, please suggest or describe an outline for one. Such a system would formalize times like:
-13,750,000,000 ± 11,000,000 (Big Bang)
1970-01-01:00:00:00 (Unix Epoch)
1 (Year 1 CE)
For example: both Geolocations and Chronolocations frequently lack precision -- this is just one consideration but I'm sure there are more.
My goal is to formalize a way to store and retrieve temporal locations of all kinds. As you might imagine this is more complex than it sounds.
I have never heard of such a system, but it would be fairly trivial to write a class where a structured data type like this exists:
struct bigTime{
signed long int millenium;
int decade;
signed long int seconds;
}time;
You could store milennia before/after an arbitrary point (even 1970 for simplicity) for long range, decades for mid range, then use seconds and milliseconds as short term.
You could create a class where adding +/- $X seconds, minutes, hours, days, weeks, months, years, decades, centuries, millenia would be straightforward.
Say you wanted to go 156 years back. that's -15 decades and -189 341 556 seconds.
Or 3205 years and 2 weeks and a day back. That's -3 millenia, -20 decades, -159 080 630 seconds.
Or even 67,000,012 years (from jonathan's offtopic joke). That's -67000 millenia, -1 decade -63 113 851.9 seconds.
All of those are from today, but would be from whatever arbitrary point you chose.
The system I describe would give you 4.2 Trillion years to work with either way down to the millisecond, and more or less minimize memory required. (I'm sure it could be brought down more if you tried)