рдЕрддрд┐рд░рд┐рдХреНрдд рдФрд░ рдЦреЛрдП рд╣реБрдП рд╕рдордп рдХреА рдХрд╣рд╛рдиреАред Py3 рдХреЗ рдЕрдиреБрд╕рд╛рд░

рдХреБрдЫ рд╣рдлреНрддреЗ рдкрд╣рд▓реЗ, рд╣рдорд╛рд░реЗ рдмреБрдирд┐рдпрд╛рджреА рдврд╛рдВрдЪреЗ рдореЗрдВ, рдореИрдВрдиреЗ рдкрд░реНрдпрд╛рд╡рд░рдг рдЪрд░ рдореЗрдВ рдПрдХ рдЫреЛрдЯреА рд╡рд┐рдиреНрдпрд╛рд╕ рддреНрд░реБрдЯрд┐ рдХреА рдЦреЛрдЬ рдХреА TZред рдЗрд╕ рддреНрд░реБрдЯрд┐ рдХрд╛ рд╕реБрдзрд╛рд░ рдмреНрд░рд╣реНрдорд╛рдВрдб рдореЗрдВ рдмрдЧ рдХреЗ рдирд╛рдЬреБрдХ рд╕рдВрддреБрд▓рди рдФрд░ рд╣рдорд╛рд░реЗ рдЧреНрд░реЗрдлрд╛рдЗрдЯ рдореЗрдВ рдПрдХ рдкрд░рд┐рдпреЛрдЬрдирд╛ рдХреЗ рд▓рд┐рдП рдЖрд░рдкреАрдПрд╕ рдЧреНрд░рд╛рдлрд┐рдХреНрд╕ рдХреЛ рд╢рд╛рдмреНрджрд┐рдХ рд░реВрдк рд╕реЗ рдкрд╛рдЧрд▓ рдмрдирд╛ рджреЗрддрд╛ рд╣реИред рдореИрдВ рдЖрдкрдХреЛ рдмрддрд╛рддрд╛ рд╣реВрдБ рдХрд┐ рдХреИрд╕реЗ рдореИрдВрдиреЗ рдХрдИ рджрд┐рдиреЛрдВ рддрдХ рдХреБрдЫ рдШрдВрдЯреЛрдВ рдХрд╛ рдкреАрдЫрд╛ рдХрд┐рдпрд╛ред


рдпреЗ рд╕рдм рдХреИрд╕реЗ рд╢реБрд░реВ рд╣реБрдЖ


рд╕реНрдХреНрд░рд┐рдкреНрдЯ, рдЬрд┐рд╕реЗ рд╣рд╛рде рд╕реЗ рд▓реЙрдиреНрдЪ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ рдФрд░ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдХрд╛рдо рдХрд┐рдпрд╛ рдерд╛, cron.d рд╕реЗ рд╢реБрд░реВ рдХрд░рддреЗ рд╕рдордп рдПрдХ рддреНрд░реБрдЯрд┐ рдлреЗрдВрдХ рджреАред рд╕рд╛рджреЗ рдкрд╛рда рдореЗрдВ рд▓реЙрдЧ рдХреЗ рдПрдХ рд╕рддрд╣реА рдЕрдзреНрдпрдпрди рдиреЗ рд╕рдВрдХреЗрдд рджрд┐рдпрд╛ рдХрд┐ рдХреНрдпрд╛ рдЧрд▓рдд рдерд╛ред


#   
$ TZ='' clickhouse-client; echo exit=$?
ClickHouse client version 20.3.2.1.
Connecting to localhost:9000 as user default.
Connected to ClickHouse server version 20.3.2 revision 54433.
Poco::Exception. Code: 1000, e.code() = 0, e.displayText() = Exception: Could not determine time zone from TZ variable value: '': filesystem error: in file_size: Is a directory [/usr/share/zoneinfo] (version 20.3.2.1)
exit=232

рд╣рдорд╛рд░реЗ рд╕рд╛рде рдпрд╛ рдХрд╛рд░реНрдпрдХреНрд░рдо рдореЗрдВ рддреНрд░реБрдЯрд┐?


рдХреНрдпрд╛ рдкреНрд░реЛрдЧреНрд░рд╛рдо рдХрд╛ рд╡реНрдпрд╡рд╣рд╛рд░ рд╕рд╣реА рд╣реИ рдпрд╛ рдпрд╣ рдмрдЧ рд╣реИ?


GNU рдкреНрд░рд▓реЗрдЦрди рдмрддрд╛рддрд╛ рд╣реИ рдХрд┐ рдкрд░реНрдпрд╛рд╡рд░рдг рдЪрд░ рдХреЗ рд▓рд┐рдП 3 рд╕рдВрднрд╛рд╡рд┐рдд рдкреНрд░рд╛рд░реВрдк рд╣реИрдВ TZ:


  • рдбреАрдПрд╕рдЯреА рдХреЗ рдмрд┐рдирд╛ рдкреНрд░рд╛рд░реВрдк (рджрд┐рди рдХреЗ рд╕рдордп рдХреА рдмрдЪрдд) std offsetред рдЙрджрд╛рд╣рд░рдг EST+5,GMT+0
  • DST рдХреЗ рд╕рд╛рде рдкреНрд░рд╛рд░реВрдк std offset dst [offset],start[/time],end[/time]:ред рдЙрджрд╛рд╣рд░рдг рд╣реИ EST+5EDT,M3.2.0/2,M11.1.0/2ред
  • рд╕рдордп рдХреНрд╖реЗрддреНрд░ рд╡рд┐рд╡рд░рдг рдлрд╝рд╛рдЗрд▓ рдХрд╛ рдирд╛рдоред рдПрдХ рдмреГрд╣рджрд╛рдиреНрддреНрд░ рдХреЗ рд╕рд╛рде рд╢реБрд░реВ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ :ред рдпрджрд┐ рдкрд╣рд▓рд╛ (рдпрд╛ рдмреГрд╣рджрд╛рдиреНрддреНрд░ рдХрд╛ рдЕрдиреБрд╕рд░рдг рдХрд░рдиреЗ рд╡рд╛рд▓рд╛) рд╡рд░реНрдг рд╕реНрд▓реИрд╢ рд╣реИ /, рддреЛ рдпрд╣ рдлрд╝рд╛рдЗрд▓ рдХрд╛ рдкреВрд░реНрдг рдкрде рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред рдпрджрд┐ рдирд╣реАрдВ, рддреЛ /usr/share/zoneinfo/${TZ}ред

рдПрдХ ClickHouse рдЧреНрд░рд╛рд╣рдХ рдХреЛ рд╕реНрдерд╛рдиреАрдп рд╕рдордп рдЬреНрдЮрд╛рди рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдХреНрдпреЛрдВ рд╣реИ?


Date DateTime DBMS timestamp, toDateTime('2020-02-02 20:20:20') (, , ) UInt32. , . TZ , , 98% .


, ClickHouse ( Poco) , . .



, . cron.d TZ, . . , 2020-04-15 2020-04-20 .



2020-04-22 ( ): " RPS "


рдЧреИрд░ UTC рд╣реЛрд╕реНрдЯ рдХрд░рддрд╛ рд╣реИ


, -, . .


self.now = int(datetime.datetime.utcnow().timestamp())
...
dt = datetime.datetime.strptime(time_str, time_format).utctimetuple()
timestamp = time.mktime(dt)

datetime.utcnow()?


Return the current UTC date and time, with tzinfo=None.
This is like now(), but returns the current UTC date and time, as a naive datetime object. An aware current UTC datetime can be obtained by calling datetime.now(timezone.utc). See also now().
Warning: Because naive datetime objects are treated by many datetime methods as local times, it is preferred to use aware datetimes to represent times in UTC. As such, the recommended way to create an object representing the current time in UTC is by calling datetime.now(timezone.utc).

, UTC, tzinfo=None datetime. .timestamp() UNIX time , UTC. : TZ=UTC


datetime.now().timestamp(). , .timestamp(), datetime.now(timezone.utc)


datetime.utctimetuple()?


datetime.timetuple():
Return time.struct_time such as returned by time.localtime().
datetime.utctimetuple():
If datetime instance d is naive, this is the same as d.timetuple() except that tm_isdst is forced to 0 regardless of what d.dst() returns. DST is never in effect for a UTC time.
If d is aware, d is normalized to UTC time, by subtracting d.utcoffset(), and a time.struct_time for the normalized time is returned. tm_isdst is forced to 0.
Warning: Because naive datetime objects are treated by many datetime methods as local times, it is preferred to use aware datetimes to represent times in UTC; as a result, using utcfromtimetuple may give misleading results. If you have a naive datetime representing UTC, use datetime.replace(tzinfo=timezone.utc) to make it aware, at which point you can use datetime.timetuple().

. time.struct_time, time.mktime(). , python2. , . , UNIX timestamp .


Python, , .


, datetime.strptime().timestamp()


TZ


, . - , - UTC, - , . , .


, RPS :


UTC рд╣реЛрд╕реНрдЯ рдХрд░рддрд╛ рд╣реИ


, , . , .


, :


  • , TZ=''
  • UTC strptime()
  • UTC, strptime()
  • strptime()

strptime 2020-04-24T05:31:55+02:00


рдкрд╛рдпрдерди рд▓рд┐рдкрд┐


#!/usr/bin/env python
from datetime import datetime, timezone  # noqa
from time import mktime
def pprint(d: dict):
    for k in d:
        print("{}: {}".format(k, d[k]))
now = {'now': datetime.now(),
       # 'now_tz': datetime.now(timezone.utc), # the same as now for timestamp
       'utcnow': datetime.utcnow()}
now_ts = [int(now[k].timestamp()) for k in now]
now_dict = {k: [now_ts[i], now_ts[i] - now_ts[0]] for i, k in enumerate(now)}
pprint(now_dict)
# pprint(now)
# print('Timestamps in now: {}'.format(set(now_ts)))
print()
ts_c = 1587699115  # the known correct value
time_format = "%Y-%m-%dT%H:%M:%S%z"
time_str = "2020-04-24T05:31:55+02:00"
timetuples = {
    'timetuple': datetime.strptime(time_str, time_format).timetuple(),
    'utctimetuple': datetime.strptime(time_str, time_format).utctimetuple(),
}
ts = {
    'timestamp': [
        int(datetime.strptime(time_str, time_format).timestamp()),
        int(datetime.strptime(time_str, time_format).timestamp()) - ts_c,
    ],
    'timetuple': [
        int(mktime(timetuples['timetuple'])),
        int(mktime(timetuples['timetuple'])) - ts_c,
    ],
    'utctimetuple': [
        int(mktime(timetuples['utctimetuple'])),
        int(mktime(timetuples['utctimetuple'])) - ts_c,
    ],
}
pprint(ts)
# pprint(timetuples)
# print('Timestamps in ts: {}'.format(set(int(v[0]) for v in ts.values())))

рдЕрд▓рдЧ рд╕реЗ рдкрд╛рдпрдерди рд╕реНрдЯрд╛рд░реНрдЯрдЕрдк рд╕реНрдХреНрд░рд┐рдкреНрдЯ TZ


#!/usr/bin/env bash
for tz in '' Europe/Moscow UTC Europe/Berlin
do
  date "+==TZ=${tz} %s=="
  TZ=$tz python example.py
  date '+++%s++' -d '2020-04-24T05:31:55+02:00'
done


TZ. , +02:00.


\ TZ''+03:00UTC+02:00 ( unset TZ)
now()/now(tz)++++
utcnow()+-+-
timestamp()++++
timetuple()+mktime()---+
utctimetuple()+mktime()+-+-

now timestamp . , timetuple + mktime .


timestamp

рдЯреВрдЯрд╛ рд╣реБрдЖ рд╕рдордпрдХреНрд╖реЗрддреНрд░ рдореВрд▓реНрдп, рдореВрд▓реНрдп TZ=''


==TZ='' 1587914590==
now: [1587914590, 0]
utcnow: [1587914590, 0]
timestamp: [1587699115, 0]
timetuple: [1587706315, 7200] - TZ - UTC
utctimetuple: [1587699115, 0]
++1587699115++

TZ='+03:00', UTC strptime()


==TZ=Europe/Moscow 1587914590==
now: [1587914590, 0]
utcnow: [1587903790, -10800] - UTC - TZ
timestamp: [1587699115, 0]
timetuple: [1587695515, -3600] - +02:00 - TZ
utctimetuple: [1587688315, -10800] - UTC - TZ
++1587699115++

TZ=UTC, strptime()


==TZ=UTC 1587914590==
now: [1587914590, 0]
utcnow: [1587914590, 0]
timestamp: [1587699115, 0]
timetuple: [1587706315, 7200] - +02:00 - UTC
utctimetuple: [1587699115, 0]
++1587699115++

TZ='+02:00', strptime(), unset TZ


==TZ=Europe/Berlin 1587914590==
now: [1587914590, 0]
utcnow: [1587907390, -7200] - UTC - TZ
timestamp: [1587699115, 0]
timetuple: [1587699115, 0]
utctimetuple: [1587695515, -3600] - UTC - TZ...    DST!
++1587699115++

, .



рдЕрджреНрднреБрдд рдЯрд┐рдХреНрдХреА рд╕реНрдЪреЗрд▓рди рдпрдереЛрдЪрд┐рдд рд╕рд▓рд╛рд╣ рджреЗрддреА рд╣реИ : "рдЕрдкрдиреЗ рдирдВрдЧреЗ рд╣рд╛рдереЛрдВ рд╕реЗ рд╕рдордп рди рд▓реЗрдВред" рдореЗрд░реЗ рд▓рд┐рдП, рдЦрддрд░реЗ рдХреА рд░реИрдВрдХрд┐рдВрдЧ рдореЗрдВ, рдпрд╣ DNS рдХреЗ рд╕рд╛рде рдПрдХ рд▓рд╛рдЗрди рдкрд░ рдЧрд┐рд░ рдЧрдпрд╛ред рдЬрдм рднреА рд╕рдВрднрд╡ рд╣реЛ рдЖрдо рддреМрд░ рдкрд░ рдЗрд╕рд╕реЗ рдмрдЪрдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░реЗрдВред


рдФрд░ рдЗрд╕ рджрд┐рд▓рдЪрд╕реНрдк рд╕рдордп рдкрд░ рдореИрдВ рд╕реНрд╡рд╕реНрде рд░рд╣рдиреЗ рдХреА рдХрд╛рдордирд╛ рдХрд░рддрд╛ рд╣реВрдВред рдШрд░ рдкрд░ рд░рд╣рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░реЗрдВ рдФрд░ рдЕрдЧрд░ рдЖрдк рдЕрдЪрд╛рдирдХ рдмрд╣реБрдд рдКрдм рдЧрдП рд╣реИрдВ рдФрд░ рдЖрдкрдХреЗ рдкрд╛рд╕ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХреБрдЫ рдирд╣реАрдВ рд╣реИ, рддреЛ рдЖрдк рдЗрдиреЛрд╣рдЧреЗрдореНрд╕ рд╕реЗ рдЧреЗрдо рдЦреЗрд▓ рд╕рдХрддреЗ рд╣реИрдВ ред рд╡реИрд╕реЗ, рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдЦреБрд▓реА рд░рд┐рдХреНрддрд┐рдпреЛрдВ рд╣реИрдВ


All Articles