ืืขืื ืืึทืืจืึทืืืขืจื. ืืืึทื ื ืืื ืืืืื ืฆื ืจืขืื ืืืขืื ืืื ืฆื ืฉืจืืึทืื ืืืื ืืืืืขื ืข ืคึผืฉืื NTP ืงืืืขื ื. ืืืืกืืงืื, ืื ืฉืืืขืก ืืืขื ืงืขืจ ืฆื ืื ืกืืจืืงืืืจ ืคืื ืื ืคึผืึทืงืึทื ืืื ืืื ืื ืขื ืืคืขืจ ืคืื ืื NTP ืกืขืจืืืขืจ ืืื ืคึผืจืึทืกืขืกื. ืืขืจ ืงืึธื ืืืขื ืืืื ืืขืฉืจืืื ืืื ืคึผืืืืึธื, ืืืืึทื, ืืื ืืืื ืืืื ืื ื, ืขืก ืืื ืคืฉืื ืงืืื ืืขืกืขืจ ืฉืคึผืจืึทื ืคึฟืึทืจ ืึทืืึท ืืืื. ืงืึทื ืึทืกืขืจื ืืืขื ืืึทืฆืึธืื ืืคืืขืจืงืืึทืืงืืื ืฆื ืื ืขื ืืขืืงืืื ืคืื ืื ืงืึธื ืืื ืื ื ืืคึผืืื ืงืึธื - ืืื ืืื ืืขืืืขื "ืื ืกืคึผืืืขืจื" ืืืจื ืขืก.
ืึทืืื ืืืึธืก ืืื NTP ืกืืึท ืืื ืกืืึท? NTP ืืื ืึท ืคึผืจืึธืืึธืงืึธื ืคึฟืึทืจ ืงืึทืืืื ืึทืงืืืืื ื ืืื ืฆืืื ืกืขืจืืืขืจืก. ืืขื ืคึผืจืึธืืึธืงืึธื ืืื ืืขื ืืฆื ืืื ืคืืืข ืืึธืืขืจื ืืืฉืื ืขื. ืคึฟืึทืจ ืืืึทืฉืคึผืื, ืื w32tm ืืื ืกื ืืืืฃ Windows.
ืขืก ืืขื ืขื 5 ืืืขืจืกืืขืก ืคืื ืื NTP ืคึผืจืึธืืึธืงืึธื ืืื ืืึทื ืฅ. ืืขืจ ืขืจืฉืืขืจ ืืืขืจืกืืข 0 (1985, RFC958) ืืื ืืขืจืืืืึทื ืืขืจืขืื ื ืืื ืคืึทืจืขืืืขืจื. ืืขืจืืืืึทื, ื ืืึทืขืจ ืึธื ืขืก ืืขื ืขื ืืขื ืืฆื, 1 (1988, RFC1059), 2 (1989, RFC1119), 3 (1992, RFC1305) ืืื 4 (1996, RFC2030). ืืืขืจืกืืขืก 1-4 ืืขื ืขื ืงืึทืืคึผืึทืืึทืืึทื ืืื ืืขืืขืจ ืื ืืขืจืข, ืืื ืืขื ืขื ืึทื ืืขืจืฉ ืืืืื ืืื ืื ืึทืืืขืจืืืึทืื ืคืื ืื ืกืขืจืืืขืจืก.
ืคึผืึทืงืึทื ืคึฟืึธืจืืึทื
ืฉืคึผืจืื ืืขื ืืจืืื (ืงืขืจืขืงืฉืึทื ืืจืืื) ืืื ืึท ื ืืืขืจ ืืืึธืก ืื ืืืงืืืฅ ืื ืฉืคึผืจืื ืืขื ืจืืข ืืืืจืขื ืื ื. ืืืึทืืฉ:
- 0 - ืงืืื ืงืขืจืขืงืฉืึทื
- 1 - ืื ืืขืฆืืข ืืื ืื ืคืื ืืขื ืืึธื ืึผืืื 61 ืกืขืงืื ืืขืก
- 2 - ืื ืืขืฆืืข ืืื ืื ืคืื ืืขื ืืึธื ืึผืืื 59 ืกืขืงืื ืืขืก
- 3 - ืกืขืจืืืขืจ ืืืจืืคืึทื (ืฆืืื ืืืืก ืคืื ืกืื ืง)
ืืืขืจืกืืข ื ืืืขืจ (ืืืขืจืกืืข ื ืืืขืจ) - NTP ืคึผืจืึธืืึธืงืึธื ืืืขืจืกืืข ื ืืืขืจ (1-4).
ืืึธืืข (ืืึธืืข) - ืึธืคึผืขืจืึทืฆืืข ืืึธืืข ืคืื โโืื ืคึผืึทืงืึทื ืกืขื ืืขืจ. ืืืขืจื ืคืื 0 ืฆื 7, ืืขืจืกื ืคึผืจืึธืกื:
- 3 - ืงืืืขื ื
- 4 - ืกืขืจืืืขืจ
- 5 - ืืจืึธืืงืึทืกื ืืึธืืข
ืฉืืืืข (ืืืืขืจืื ื ืืืจืื) - ืื ื ืืืขืจ ืคืื ืื ืืขืจืืืืืื ืืืึทืขืจืก ืฆืืืืฉื ืื ืกืขืจืืืขืจ ืืื ืื ืจืขืคึฟืขืจืขื ืฅ ืืืืืขืจ (1 - ืืขืจ ืกืขืจืืืขืจ ื ืขืื ืืึทืื ืืืืึทื ืคืื ืื ืจืขืคึฟืขืจืขื ืฅ ืืืืืขืจ, 2 - ืืขืจ ืกืขืจืืืขืจ ื ืขืื ืืึทืื ืคึฟืื ืื ืกืขืจืืืขืจ ืืื ืืืจืื 1, ืืื"ื ื).
ืืขืงื ืืื ืึท ืืขืืชืืขื ืืึทื ืฅ ื ืืืขืจ ืจืขืคึผืจืืืขื ืืื ื ืื ืืึทืงืกืืืื ืืขืืึทืืขื ืฆืืืืฉื ืงืึธื ืกืขืงืืืืืืข ืึทืจืืืงืืขื. ืืขืจ NTP ืงืืืขื ื ืกืคึผืขืฆืืคืืฆืืจื ืืึธ ืื ืืขืืึทืืขื ืืื ืืืึธืก ืขืจ ืืงืกืคึผืขืงืฅ ืฆื ืืึทืงืืืขื ืื ืกืขืจืืืขืจ, ืืื ืืขืจ NTP ืกืขืจืืืขืจ ืกืคึผืขืฆืืคืืฆืืจื ืื ืืขืืึทืืขื ืืื ืืืึธืก ืขืก ืืงืกืคึผืขืงืฅ ืฆื ืืืื ืคึผืึธืืื. ืื ืืืขืจื ืืื ืืืืึทื ืฆื ืื ืืืื ืขืจื ืืึธืืึทืจืืืื ืคืื ืกืขืงืื ืืขืก.
ืคึผืื ืืืขืืงืืึทื (ืคึผืื ืืืขืืงืืึทื) ืืื ืึท ืืขืืชืืขื ืืึทื ืฅ ื ืืืขืจ ืจืขืคึผืจืืืขื ืืื ื ืื ืึทืงืืขืจืึทืกื ืคืื ืื ืกืืกืืขื ืืืืืขืจ. ืื ืืืขืจื ืืื ืืืืึทื ืฆื ืื ืืืื ืขืจื ืืึธืืึทืจืืืื ืคืื ืกืขืงืื ืืขืก.
ืืืึธืจืฆื ืคืึทืจืืึทืืื (ืกืขืจืืืขืจ ืืืืืึทื ืกื) ืืื ืื ืฆืืื ืขืก ื ืขืื ืคึฟืึทืจ ืื ืืืืืขืจ ืฆื ืืขืจืืจืืืื ืื NTP ืกืขืจืืืขืจ, ืืื ืึท ืคืึทืจืคืขืกืืืงื ื ืืืขืจ ืคืื ืกืขืงืื ืืขืก.
ืืืึธืจืฆื ืืืกืคึผืขืจืฉืึทื (ืกืขืจืืืขืจ ืฆืขืืืึธืจืคื) - ืื ืฆืขืืืึธืจืคื ืคืื ืื NTP ืกืขืจืืืขืจ ืืืืืขืจ ืืื ืึท ืคืึทืจืคืขืกืืืงื-ืคืื ื ื ืืืขืจ ืคืื ืกืขืงืื ืืขืก.
Ref ID (ืืงืืจ ืฉืืึทื) - ืืืึทื ืฉืืึทื. ืืืื ืืขืจ ืกืขืจืืืขืจ ืืื ืกืืจืึทืืื 1, ืจืขืฃ ืฉืืึทื ืืื ืืขืจ ื ืึธืืขื ืคืื ืื ืึทืืึธืืืฉืข ืืืืืขืจ (4 ASCII ืืืชืืืช). ืืืื ืืขืจ ืกืขืจืืืขืจ ื ืืฆื ืื ืื ืืขืจ ืกืขืจืืืขืจ, ืืขืจ ืจืขืฃ ืฉืืึทื ืึผืืื ืื ืึทืืจืขืก ืคืื ืืขื ืกืขืจืืืขืจ.
ืื ืืขืฆืืข 4 ืคืขืืืขืจ ืจืขืคึผืจืึทืืขื ืฅ ืื ืฆืืื - 32 ืืืฅ - ืื ืื ืืึทืืืฉืขืจ ืืืื, 32 ืืืฅ - ืื ืคืจืึทืงืฉืึทื ืึทื ืืืื.
ืืขืจืืึธื ืขื - ืื ืืขืฆืืข ืืืืืขืจ ืืืืฃ ืื ืกืขืจืืืขืจ.
ืึธืจืืืื ืึทืืข - ืฆืืื ืืืขื ืื ืคึผืึทืงืึทื ืืื ืืขืฉืืงื (ืึธื ืืขืคืืื ืืืจื ืื ืกืขืจืืืขืจ - ืืขืจ ืืืขืื ืืขื ืืื ืื).
ืืึทืงืืืขื - ืฆืืื ืืืขื ืื ืคึผืึทืงืึทื ืืื ืืืงืืืขื ืืืจื ืื ืกืขืจืืืขืจ.
ืืืขืจืฉืืงื - ืฆืืื ืืืขื ืื ืคึผืึทืงืึทื ืืื ืืขืฉืืงื ืคืื ืื ืกืขืจืืืขืจ ืฆื ืืขื ืงืืืขื ื (ืึธื ืืขืคืืื ืืืจื ืืขื ืงืืืขื ื, ืืขืจ ืืืขืื ืืขื ืืื ืื).
ืื ืืขืฆืืข ืฆืืืื ืคืขืืืขืจ ืืืขื ื ืื ืืืื ืืึทืืจืึทืื.
ืืืืืจ ืฉืจืืืื ืืื ืืขืจ ืคืขืงื:
ืคึผืขืงื ืงืึธื
class NTPPacket:
_FORMAT = "!B B b b 11I"
def __init__(self, version_number=2, mode=3, transmit=0):
# Necessary of enter leap second (2 bits)
self.leap_indicator = 0
# Version of protocol (3 bits)
self.version_number = version_number
# Mode of sender (3 bits)
self.mode = mode
# The level of "layering" reading time (1 byte)
self.stratum = 0
# Interval between requests (1 byte)
self.pool = 0
# Precision (log2) (1 byte)
self.precision = 0
# Interval for the clock reach NTP server (4 bytes)
self.root_delay = 0
# Scatter the clock NTP-server (4 bytes)
self.root_dispersion = 0
# Indicator of clocks (4 bytes)
self.ref_id = 0
# Last update time on server (8 bytes)
self.reference = 0
# Time of sending packet from local machine (8 bytes)
self.originate = 0
# Time of receipt on server (8 bytes)
self.receive = 0
# Time of sending answer from server (8 bytes)
self.transmit = transmit
ืฆื ืฉืืงื (ืืื ืืึทืงืืืขื) ืึท ืคึผืึทืงืึทื ืฆื ืื ืกืขืจืืืขืจ, ืืืจ ืืืื ืงืขื ืขื ืฆื ืืืขื ืื ืขืก ืืื ืึท ืืขื ืืข ืคืื โโืืืืขืก.
ืคึฟืึทืจ ืืขื (ืืื ืคืึทืจืงืขืจื) ืึธืคึผืขืจืึทืฆืืข, ืืืจ ืืืขืื ืฉืจืืึทืื ืฆืืืื ืคืึทื ืืงืฉืึทื ื - ืคึผืึทืง () ืืื ืึทื ืคึผืึทืง ():
ืคึผืึทืง ืคึฟืื ืงืฆืืข
def pack(self):
return struct.pack(NTPPacket._FORMAT,
(self.leap_indicator << 6) +
(self.version_number << 3) + self.mode,
self.stratum,
self.pool,
self.precision,
int(self.root_delay) + get_fraction(self.root_delay, 16),
int(self.root_dispersion) +
get_fraction(self.root_dispersion, 16),
self.ref_id,
int(self.reference),
get_fraction(self.reference, 32),
int(self.originate),
get_fraction(self.originate, 32),
int(self.receive),
get_fraction(self.receive, 32),
int(self.transmit),
get_fraction(self.transmit, 32))
ืึทื ืคึผืึทืง ืคึฟืื ืงืฆืืข
def unpack(self, data: bytes):
unpacked_data = struct.unpack(NTPPacket._FORMAT, data)
self.leap_indicator = unpacked_data[0] >> 6 # 2 bits
self.version_number = unpacked_data[0] >> 3 & 0b111 # 3 bits
self.mode = unpacked_data[0] & 0b111 # 3 bits
self.stratum = unpacked_data[1] # 1 byte
self.pool = unpacked_data[2] # 1 byte
self.precision = unpacked_data[3] # 1 byte
# 2 bytes | 2 bytes
self.root_delay = (unpacked_data[4] >> 16) +
(unpacked_data[4] & 0xFFFF) / 2 ** 16
# 2 bytes | 2 bytes
self.root_dispersion = (unpacked_data[5] >> 16) +
(unpacked_data[5] & 0xFFFF) / 2 ** 16
# 4 bytes
self.ref_id = str((unpacked_data[6] >> 24) & 0xFF) + " " +
str((unpacked_data[6] >> 16) & 0xFF) + " " +
str((unpacked_data[6] >> 8) & 0xFF) + " " +
str(unpacked_data[6] & 0xFF)
self.reference = unpacked_data[7] + unpacked_data[8] / 2 ** 32 # 8 bytes
self.originate = unpacked_data[9] + unpacked_data[10] / 2 ** 32 # 8 bytes
self.receive = unpacked_data[11] + unpacked_data[12] / 2 ** 32 # 8 bytes
self.transmit = unpacked_data[13] + unpacked_data[14] / 2 ** 32 # 8 bytes
return self
ืคึฟืึทืจ ืคืืื ืืขื ืืฉื, ืืื ืึท ืึทืคึผืืึทืงืืืฉืึทื - ืงืึธื ืืืึธืก ืืืจื ืก ืืขื ืคึผืขืงื ืืื ืึท ืฉืืื ืฉืืจืืงื
def to_display(self):
return "Leap indicator: {0.leap_indicator}n"
"Version number: {0.version_number}n"
"Mode: {0.mode}n"
"Stratum: {0.stratum}n"
"Pool: {0.pool}n"
"Precision: {0.precision}n"
"Root delay: {0.root_delay}n"
"Root dispersion: {0.root_dispersion}n"
"Ref id: {0.ref_id}n"
"Reference: {0.reference}n"
"Originate: {0.originate}n"
"Receive: {0.receive}n"
"Transmit: {0.transmit}"
.format(self)
ืฉืืงื ืึท ืคึผืขืงื ืฆื ืื ืกืขืจืืืขืจ
ืฉืืงื ืึท ืคึผืึทืงืึทื ืืื ืึธื ืืขืคืืื ืคืขืืืขืจ ืฆื ืื ืกืขืจืืืขืจ ืืืขืจืกืืข, ืืึธืืข ะธ ืืืขืจืฉืืงื. ืื ืืืขืจืฉืืงื ืืืจ ืืืื ืกืคึผืขืฆืืคืืฆืืจื ืื ืงืจืึทื ื ืฆืืื ืืืืฃ ืื ืืืืข ืืึทืฉืื (ื ืืืขืจ ืคืื ืกืขืงืื ืืขืก ืืื ื ืืื ืืืจ 1, 1900), ืืืขืจืกืืข - ืงืืื ืคืื 1-4, ืืึธืืข - 3 (ืงืืืขื ื ืืึธืืข).
ืืขืจ ืกืขืจืืืขืจ, ื ืึธื ืืืงืืืขื ืื ืืงืฉื, ืคึผืืึธืืืืจื ืึทืืข ืื ืคืขืืืขืจ ืืื ืื NTP ืคึผืึทืงืึทื, ืงืึทืคึผืืื ื ืืื ืื ืคืขืื ืึธืจืืืื ืึทืืข ืืืขืจื ืคืื ืืืขืจืฉืืงื, ืืื ืก ืื ื ืืขืงืืืข ื ืื ื ืืข ืจ ืืงืฉื . ืขืก ืืื ืึท ืืืกืืขืจืืข ืคึฟืึทืจ ืืืจ ืืืึธืก ืืขืจ ืงืืืขื ื ืงืขื ื ืืฉื ืืื ืคึผืืึธืืืืจื ืื ืืืขืจื ืคืื ืืืื ืฆืืื ืืื ืืขื ืคืขืื ืึธืจืืืื ืึทืืข. ืืื ืึท ืจืขืืืืืึทื, ืืืขื ืื ืคึผืึทืงืึทื ืงืืื ืฆืืจืืง, ืืขืจ ืงืืืขื ื ืืื 4 ืฆืืื ืืืึทืืืขืก - ืื ืฆืืื ืืืขื ืื ืืขืื ืืื ืืขืฉืืงื (ืึธืจืืืื ืึทืืข), ืื ืฆืืื ืืืขื ืืขืจ ืกืขืจืืืขืจ ืืื ืืืงืืืขื ืื ืืงืฉื (ืืึทืงืืืขื), ืื ืฆืืื ืืืขื ืืขืจ ืกืขืจืืืขืจ ืืึธื ืืขืฉืืงื ืืขื ืขื ืืคืขืจ (ืืืขืจืฉืืงื) ืืื ืื ืฆืืื ืคืื ืงืึทืืึธืืข ืคืื โโืึท ืขื ืืคืขืจ ืืืจื ืืขื ืงืืืขื ื - ืึธื ืงืืืขื (ื ืืฉื ืืื ืืขื ืคึผืขืงื). ืืื ืื ืืืึทืืืขืก ืืืจ ืงืขื ืขื ืฉืืขืื ืื ืจืืืืืง ืฆืืื.
ืคึผืขืงื ืฉืืงื ืืื ืจืืกืืืืื ื ืงืึธื
# Time difference between 1970 and 1900, seconds
FORMAT_DIFF = (datetime.date(1970, 1, 1) - datetime.date(1900, 1, 1)).days * 24 * 3600
# Waiting time for recv (seconds)
WAITING_TIME = 5
server = "pool.ntp.org"
port = 123
packet = NTPPacket(version_number=2, mode=3, transmit=time.time() + FORMAT_DIFF)
answer = NTPPacket()
with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as s:
s.settimeout(WAITING_TIME)
s.sendto(packet.pack(), (server, port))
data = s.recv(48)
arrive_time = time.time() + FORMAT_DIFF
answer.unpack(data)
ืืึทืื ืคึผืจืึทืกืขืกืื ื ืคืื ืื ืกืขืจืืืขืจ
ืื ืคึผืจืึทืกืขืกืื ื ืคืื ืืึทืื ืคืื ืื ืกืขืจืืืขืจ ืืื ืขื ืืขื ืฆื ืื ืึทืงืฉืึทื ื ืคืื ืื ืขื ืืืืฉ ืืืฉืขื ืืืืขื ืคืื ืืขืจ ืึทืื ืคึผืจืึธืืืขื ืคืื Raymond M. Smallian (1978): "ืืืื ืืขื ืืฉ ืืื ื ืืฉื ืืึธืื ืึท ืืึทื ืืืขืืขื ืง, ืึธืืขืจ ืขืก ืืื ืืขืืืขื ืึท ืคึผืื ืืืขื ืืืึทื ื ืืืืืขืจ ืืื ืฉืืื, ืืืึธืก ืขืจ ืืื ืคืืจืืขืกื ืฆื ืืืื ื. ืืืื ืืื, ืคืืจืืขืื ืืืง ืืืืืขืจ ืื ืฆืืืืืื ืืขื ืืืืืขืจ, ืืื ืขืจ ืืขืืื ืืขื ืืืืืื ืืืื ืคืจืืื ื, ืคืืจืืจืืื ืืื ืืื ืืขื ืึธืืื ื, ืืื ืืืขื ืขืจ ืืื ืฆืืจืืง ืึทืืืื, ืืื ืขืจ ืืขืืื ืื ืฆื ืฉืืขืื ืืขื ืืืืืขืจ ืจืืืืืง. ืืื ืืื ืขืจ ืืขืจืืื ืฆื ืืึธื ืืึธืก ืืืื ืื ืจืืืืข ืฆืืื ืืื ื ืืฉื ืืืงืื ื ืืื ืฉืืืึทืื? ืืขืจ ืขื ืืคึฟืขืจ ืืื: โืคึฟืึทืจืืึธืื ืืืง ืคึฟืื ืฉืืื, ืืืื ืื ืึท ืืขื ืืฉ ืืืืคึฟื ืืืืืขืจ ืืื ืืขืืขื ืงื ืื ืฉืืขืืข ืคึฟืื ืื ืืขื ื. ืงืืืขื ืฆื ืึท ืคืจืืึทื ื ืืื ืืึธืื ืื ืืขืกื, ืขืจ ืืืืขืจืงื ืื ืฆืืึทื ืคืื ืืืื ืึธื ืงืืืขื ืืื ืึทืืืขืงืืืื. ืืึธืก ืึทืืึทืื ืืื ืฆื ืืขืคึฟืื ืขื ืืืืก ืืื ืืึทื ื ืขืจ ืืื ืึทืืืขืง. ืืืืืขืงืขืจื ืืืื ืืื ืงืืง ืืืึท ืื ืืืืืขืจ, ืึท ืืขื ืืฉ ืืึทืฉืืืื ืื ืืขืืืืขืจ ืคืื ืืืื ืึทืืืขืง. ืืจืืคื ืขืืขื ืคืื ืืขืจ ืฆืืื ืื ืฆืืื ืืืืก ืขืจ ืืื ืคืืจืืจืืื ืฆื ืืืืืื, ืืขืจืืื ืขื ืืขืจ ืืขื ืืฉ ืื ืฆืืื ืืืืก ืขืจ ืืื ืคืืจืืจืืื ืืืืคื ืืืขื ืืืื ืืื ืฆืืจืืง. ืืืจื ืฆืืืขืื ืืึทืื ืคืื ืื ืฆืืื ืืืึธืก ืืื ืคืืจืืจืืื ืืืืฃ ืื ืืืขื ืฆื ืื ืฆืืื ืคืื ืคืึทืจืืึธืื ืื ืืขืกื, ืขืจ ืืึทืงืืืขื ืื ืืขืืขืื ืืืื ืฆื ืืขืคึฟืื ืขื ืืืืก ืื ืฆืืื ืคืื ืึธื ืงืืืขื ืึทืืืื ืืื ืกืืจืืืขืจื ืื ืืืืืื ืคืื ืืืื ืืืืืขืจ.
ืืขืคึฟืื ืขื ืื ืฆืืื ืืืึธืก ืื ืกืขืจืืืขืจ ืืื ืืจืืขืื ืืืืฃ ืื ืืงืฉื:
- ืืขืคึฟืื ืขื ืื ืคึผืึทืงืึทื ืจืืืืข ืฆืืื ืคืื ืืขื ืงืืืขื ื ืฆื ืื ืกืขืจืืืขืจ: ((ืึธื ืงืืืขื - ืึธืจืืืื ืึทืืข) - (ืืจืึทื ืกืืื - ืืึทืงืืืขื)) / 2
- ืืขืคึฟืื ืขื ืื ืืืืืง ืฆืืืืฉื ืงืืืขื ื ืืื ืกืขืจืืืขืจ ืฆืืื:
ืืึทืงืืืขื - ืึธืจืืืื ืึทืืข - ((ืงืืืขื - ืึธืจืืืื ืึทืืข) - (ืืจืึทื ืกืืื - ืืึทืงืืืขื)) / 2 =
2 * ืืึทืงืืืขื - 2 * ืึธืจืืืื ืึทืืข - ืึธื ืงืืืขื + ืึธืจืืืื ืึทืืข + ืืจืึทื ืกืืื - ืืึทืงืืืขื =
ืืึทืงืืืขื - ืึธืจืืืื ืึทืืข - ืึธื ืงืืืขื + ืืจืึทื ืกืืื
ืืืจ ืืืืื ืื ืืืงืืืขื ืืืขืจื ืฆื ืื ืืืืข ืฆืืื ืืื ืื ืื ืืขืื.
ืจืขืืืืืึทื ืจืขืืืืืึทื
time_different = answer.get_time_different(arrive_time)
result = "Time difference: {}nServer time: {}n{}".format(
time_different,
datetime.datetime.fromtimestamp(time.time() + time_different).strftime("%c"),
answer.to_display())
print(result)
ื ืืฆืืง
ืืงืืจ: www.habr.com