Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to calculate the current month from python time.time()

I'm trying to get the current number of month which is 3(Today is 04.03.2016). So I'm running:

from time import time
Ys=12*30*24*3600
Ms=Ys/12
m=(trunc(time())%Ys)/Ms
print m

and the result is 10.

Interestingly when I run:

Ds=Ms/30
d=(trunc(time())%Ms)/Ds

then the result is correct : 4.

Why m is not 3 but 10?

like image 338
judoka_acl Avatar asked Dec 24 '22 08:12

judoka_acl


1 Answers

Here's how to convert the Unix epoch time to the (UTC) Gregorian date without using any library functions. The code below only imports time to verify that the calculated date is identical to that returned by time.gmtime.

Please beware that at 03:14:08 UTC on Tuesday, 19 January 2038, 32-bit versions of the Unix time stamp will cease to work, as it will overflow the largest value that can be held in a signed 32-bit number. So do not attempt to call time.gmtime for such timestamps on a 32 bit system. Of course, the algorithm used below does not suffer from such limitations.

#!/usr/bin/env python

''' Convert Unix Epoch seconds to (proleptic) Gregorian date

    Algorithm by E. G. Richards, https://en.wikipedia.org/wiki/Julian_day

    See http://stackoverflow.com/q/35796786/4014959

    Python implementation by PM 2Ring 2016.03.07
'''

from time import gmtime

def epoch_seconds_to_gregorian_date(eseconds):
    # Algorithm parameters for Gregorian calendar
    y = 4716; j = 1401; m = 2; n = 12; r = 4; p = 1461 
    v = 3; u = 5; s = 153; w = 2; B = 274277; C = -38

    #Julian day, rounded
    J = int(0.5 + eseconds / 86400.0 + 2440587.5)

    f = J + j + (((4 * J + B) // 146097) * 3) // 4 + C
    e = r * f + v
    g = (e % p) // r
    h = u * g + w
    D = (h % s) // u + 1
    M = (h // s + m) % n + 1
    Y = (e // p) - y + (n + m - M) // n

    return Y, M, D

# Tests    
def test(s):
    t = gmtime(s)
    gmdate = t.tm_year, t.tm_mon, t.tm_mday
    e2gdate = epoch_seconds_to_gregorian_date(s)
    assert gmdate == e2gdate, (t, gmdate, e2gdate)
    return '%d.%d.%d' % e2gdate    

print 'hours'
for i in xrange(25):
    s = 3600 * i
    print i, test(s) 

print '\ndays'
for i in xrange(32):
    s = 86400 * i
    print i, test(s)

print '\n2 days by seconds...'
for s in xrange(86400 * 2):
    test(s)

n = 50
print '\n%d years by days...' % n
for i in xrange(365 * n):
    s = 86400 * i    
    test(s)

print 'Ok'    

output

hours
0 1970.1.1
1 1970.1.1
2 1970.1.1
3 1970.1.1
4 1970.1.1
5 1970.1.1
6 1970.1.1
7 1970.1.1
8 1970.1.1
9 1970.1.1
10 1970.1.1
11 1970.1.1
12 1970.1.1
13 1970.1.1
14 1970.1.1
15 1970.1.1
16 1970.1.1
17 1970.1.1
18 1970.1.1
19 1970.1.1
20 1970.1.1
21 1970.1.1
22 1970.1.1
23 1970.1.1
24 1970.1.2

days
0 1970.1.1
1 1970.1.2
2 1970.1.3
3 1970.1.4
4 1970.1.5
5 1970.1.6
6 1970.1.7
7 1970.1.8
8 1970.1.9
9 1970.1.10
10 1970.1.11
11 1970.1.12
12 1970.1.13
13 1970.1.14
14 1970.1.15
15 1970.1.16
16 1970.1.17
17 1970.1.18
18 1970.1.19
19 1970.1.20
20 1970.1.21
21 1970.1.22
22 1970.1.23
23 1970.1.24
24 1970.1.25
25 1970.1.26
26 1970.1.27
27 1970.1.28
28 1970.1.29
29 1970.1.30
30 1970.1.31
31 1970.2.1

2 days by seconds...

50 years by days...
Ok

Here's an improved version that also returns hours, minutes, and seconds. This code handles fractional seconds, however, the fields of time.struct_time are all integers, so my test function cannot be used with fractional seconds.

#!/usr/bin/env python

''' Convert Unix Epoch seconds to (proleptic) Gregorian date

    Algorithm by E. G. Richards, https://en.wikipedia.org/wiki/Julian_day

    See http://stackoverflow.com/q/35796786/4014959

    Python implementation by PM 2Ring 2016.03.07
'''

from time import time, gmtime
from random import randint
import sys    

def epoch_seconds_to_gregorian_date(eseconds):
    # Algorithm parameters for Gregorian calendar
    y = 4716; j = 1401; m = 2; n = 12; r = 4; p = 1461 
    v = 3; u = 5; s = 153; w = 2; B = 274277; C = -38

    #Julian day, rounded
    J = int(0.5 + eseconds / 86400.0 + 2440587.5)

    #Date calculation
    f = J + j + (((4 * J + B) // 146097) * 3) // 4 + C
    e = r * f + v
    g = (e % p) // r
    h = u * g + w
    D = (h % s) // u + 1
    M = (h // s + m) % n + 1
    Y = (e // p) - y + (n + m - M) // n

    #Time calculation
    seconds = eseconds % 86400
    t = int(seconds)
    hr, t = divmod(t, 3600)
    mn = t // 60
    seconds -= 3600 * hr + 60 * mn

    return Y, M, D, hr, mn, seconds

# Tests
def test(s):
    t = gmtime(s)
    gmdate = t.tm_year, t.tm_mon, t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec
    e2gdate = epoch_seconds_to_gregorian_date(s)
    assert gmdate == e2gdate, (s, gmdate, e2gdate)
    return '%d.%02d.%02d %02d:%02d:%06.3f' % e2gdate

print 'now'
s = time()
print s, epoch_seconds_to_gregorian_date(s), gmtime(s)

print '\nhours'
for i in xrange(25):
    s = 3600 * i
    print i, test(s) 

print '\ndays'
for i in xrange(32):
    s = 86400 * i
    print i, test(s)

print '\n2 days by seconds...'
for i in xrange(86400 * 2):
    test(i)
    if i % 10000 == 0:
        sys.stderr.write('.')
sys.stderr.write('\n')

n = 50
print '\n%d years by days...' % n
for i in xrange(365 * n):
    s = 86400 * i    
    test(s)    

n = 500000
print '\nRandom seconds'
for i in xrange(n):
    s = randint(0, 2147483647)
    test(s)
    if i % 10000 == 0:
        sys.stderr.write('.')
sys.stderr.write('\n')

print 'Ok'

output

now
1457355412.48 (2016, 3, 7, 12, 56, 52.476011991500854) time.struct_time(tm_year=2016, tm_mon=3, tm_mday=7, tm_hour=12, tm_min=56, tm_sec=52, tm_wday=0, tm_yday=67, tm_isdst=0)

hours
0 1970.01.01 00:00:00.000
1 1970.01.01 01:00:00.000
2 1970.01.01 02:00:00.000
3 1970.01.01 03:00:00.000
4 1970.01.01 04:00:00.000
5 1970.01.01 05:00:00.000
6 1970.01.01 06:00:00.000
7 1970.01.01 07:00:00.000
8 1970.01.01 08:00:00.000
9 1970.01.01 09:00:00.000
10 1970.01.01 10:00:00.000
11 1970.01.01 11:00:00.000
12 1970.01.01 12:00:00.000
13 1970.01.01 13:00:00.000
14 1970.01.01 14:00:00.000
15 1970.01.01 15:00:00.000
16 1970.01.01 16:00:00.000
17 1970.01.01 17:00:00.000
18 1970.01.01 18:00:00.000
19 1970.01.01 19:00:00.000
20 1970.01.01 20:00:00.000
21 1970.01.01 21:00:00.000
22 1970.01.01 22:00:00.000
23 1970.01.01 23:00:00.000
24 1970.01.02 00:00:00.000

days
0 1970.01.01 00:00:00.000
1 1970.01.02 00:00:00.000
2 1970.01.03 00:00:00.000
3 1970.01.04 00:00:00.000
4 1970.01.05 00:00:00.000
5 1970.01.06 00:00:00.000
6 1970.01.07 00:00:00.000
7 1970.01.08 00:00:00.000
8 1970.01.09 00:00:00.000
9 1970.01.10 00:00:00.000
10 1970.01.11 00:00:00.000
11 1970.01.12 00:00:00.000
12 1970.01.13 00:00:00.000
13 1970.01.14 00:00:00.000
14 1970.01.15 00:00:00.000
15 1970.01.16 00:00:00.000
16 1970.01.17 00:00:00.000
17 1970.01.18 00:00:00.000
18 1970.01.19 00:00:00.000
19 1970.01.20 00:00:00.000
20 1970.01.21 00:00:00.000
21 1970.01.22 00:00:00.000
22 1970.01.23 00:00:00.000
23 1970.01.24 00:00:00.000
24 1970.01.25 00:00:00.000
25 1970.01.26 00:00:00.000
26 1970.01.27 00:00:00.000
27 1970.01.28 00:00:00.000
28 1970.01.29 00:00:00.000
29 1970.01.30 00:00:00.000
30 1970.01.31 00:00:00.000
31 1970.02.01 00:00:00.000

2 days by seconds...
..................

50 years by days...

Random seconds
..................................................
Ok
like image 156
PM 2Ring Avatar answered Jan 09 '23 21:01

PM 2Ring