souripresident
@souripresident

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

Python NTPサーバーから現在の時間を受け取るプログラムにおけるエラー

解決したいこと

ntpサーバーから現在の時間を受け取って、PC内蔵の時間との誤差を算出し、正確に指定した時間までwaitさせるプログラムを作りました。概ね成功するのですがたまにエラーで実行されていない時があります。このエラーの意味と防止する方法を知りたいです。

発生している問題・エラー

TimeoutError                              Traceback (most recent call last)
File ~\anaconda3\Lib\site-packages\ntplib.py:318, in NTPClient.request(self, host, version, port, timeout)
    317 while src_addr[0] != sockaddr[0]:
--> 318     response_packet, src_addr = s.recvfrom(256)
    320 # build the destination timestamp

TimeoutError: timed out

During handling of the above exception, another exception occurred:

NTPException                              Traceback (most recent call last)
Cell In[7], line 8, in MyNTPClient.get_nowtime(self, timeformat)
      7 try:
----> 8     response = self.ntp_client.request(self.ntp_server_host, version=4)
      9     nowtime = datetime.utcfromtimestamp(response.tx_time) + timedelta(hours=9)

File ~\anaconda3\Lib\site-packages\ntplib.py:323, in NTPClient.request(self, host, version, port, timeout)
    322 except socket.timeout:
--> 323     raise NTPException("No response received from %s." % host)
    324 finally:

NTPException: No response received from ntp.nict.jp.

During handling of the above exception, another exception occurred:

SystemExit                                Traceback (most recent call last)
    [... skipping hidden 1 frame]

Cell In[7], line 15
     14 ntp_client = MyNTPClient()
---> 15 ntp_time = ntp_client.get_nowtime()
     16 local_time = datetime.now()

Cell In[7], line 12, in MyNTPClient.get_nowtime(self, timeformat)
     11 except Exception as e:
---> 12     sys.exit(f"Error: {e}")

SystemExit: Error: No response received from ntp.nict.jp.

During handling of the above exception, another exception occurred:

AttributeError                            Traceback (most recent call last)
    [... skipping hidden 1 frame]

File ~\anaconda3\Lib\site-packages\IPython\core\interactiveshell.py:2121, in InteractiveShell.showtraceback(self, exc_tuple, filename, tb_offset, exception_only, running_compiled_code)
   2118 if exception_only:
   2119     stb = ['An exception has occurred, use %tb to see '
   2120            'the full traceback.\n']
-> 2121     stb.extend(self.InteractiveTB.get_exception_only(etype,
   2122                                                      value))
   2123 else:
   2125     def contains_exceptiongroup(val):

File ~\anaconda3\Lib\site-packages\IPython\core\ultratb.py:710, in ListTB.get_exception_only(self, etype, value)
    702 def get_exception_only(self, etype, value):
    703     """Only print the exception type and message, without a traceback.
    704 
    705     Parameters
   (...)
    708     value : exception value
    709     """
--> 710     return ListTB.structured_traceback(self, etype, value)

File ~\anaconda3\Lib\site-packages\IPython\core\ultratb.py:568, in ListTB.structured_traceback(self, etype, evalue, etb, tb_offset, context)
    565     chained_exc_ids.add(id(exception[1]))
    566     chained_exceptions_tb_offset = 0
    567     out_list = (
--> 568         self.structured_traceback(
    569             etype,
    570             evalue,
    571             (etb, chained_exc_ids),  # type: ignore
    572             chained_exceptions_tb_offset,
    573             context,
    574         )
    575         + chained_exception_message
    576         + out_list)
    578 return out_list

File ~\anaconda3\Lib\site-packages\IPython\core\ultratb.py:1435, in AutoFormattedTB.structured_traceback(self, etype, evalue, etb, tb_offset, number_of_lines_of_context)
   1433 else:
   1434     self.tb = etb
-> 1435 return FormattedTB.structured_traceback(
   1436     self, etype, evalue, etb, tb_offset, number_of_lines_of_context
   1437 )

File ~\anaconda3\Lib\site-packages\IPython\core\ultratb.py:1326, in FormattedTB.structured_traceback(self, etype, value, tb, tb_offset, number_of_lines_of_context)
   1323 mode = self.mode
   1324 if mode in self.verbose_modes:
   1325     # Verbose modes need a full traceback
-> 1326     return VerboseTB.structured_traceback(
   1327         self, etype, value, tb, tb_offset, number_of_lines_of_context
   1328     )
   1329 elif mode == 'Minimal':
   1330     return ListTB.get_exception_only(self, etype, value)

File ~\anaconda3\Lib\site-packages\IPython\core\ultratb.py:1173, in VerboseTB.structured_traceback(self, etype, evalue, etb, tb_offset, number_of_lines_of_context)
   1164 def structured_traceback(
   1165     self,
   1166     etype: type,
   (...)
   1170     number_of_lines_of_context: int = 5,
   1171 ):
   1172     """Return a nice text document describing the traceback."""
-> 1173     formatted_exception = self.format_exception_as_a_whole(etype, evalue, etb, number_of_lines_of_context,
   1174                                                            tb_offset)
   1176     colors = self.Colors  # just a shorthand + quicker name lookup
   1177     colorsnormal = colors.Normal  # used a lot

File ~\anaconda3\Lib\site-packages\IPython\core\ultratb.py:1063, in VerboseTB.format_exception_as_a_whole(self, etype, evalue, etb, number_of_lines_of_context, tb_offset)
   1060 assert isinstance(tb_offset, int)
   1061 head = self.prepare_header(str(etype), self.long_header)
   1062 records = (
-> 1063     self.get_records(etb, number_of_lines_of_context, tb_offset) if etb else []
   1064 )
   1066 frames = []
   1067 skipped = 0

File ~\anaconda3\Lib\site-packages\IPython\core\ultratb.py:1131, in VerboseTB.get_records(self, etb, number_of_lines_of_context, tb_offset)
   1129 while cf is not None:
   1130     try:
-> 1131         mod = inspect.getmodule(cf.tb_frame)
   1132         if mod is not None:
   1133             mod_name = mod.__name__

AttributeError: 'tuple' object has no attribute 'tb_frame'

該当するソースコード

class MyNTPClient:
    def __init__(self, ntp_server_host='ntp.nict.jp'):
        self.ntp_client = ntplib.NTPClient()
        self.ntp_server_host = ntp_server_host

    def get_nowtime(self, timeformat='%Y-%m-%d %H:%M:%S'):
        try:
            response = self.ntp_client.request(self.ntp_server_host, version=4)
            nowtime = datetime.utcfromtimestamp(response.tx_time) + timedelta(hours=9)
            return nowtime
        except Exception as e:
            sys.exit(f"Error: {e}")

ntp_client = MyNTPClient()
ntp_time = ntp_client.get_nowtime()
local_time = datetime.now()
time_diff = (local_time - ntp_time).total_seconds()
print(f"NTPサーバー時刻 (JST): {ntp_time}")
print(f"ローカルシステム時刻: {local_time}")
print(time_diff)

start_time = datetime(2024,11,15,17,59,59,950000)
sleep_time = start_time - local_time
time.sleep(sleep_time.total_seconds()+time_diff)
print(local_time)
print(datetime.now())
print(ntp_client.get_nowtime())
0

2Answer

概ね成功するのですがたまにエラーで実行されていない時があります。

何度実行してもntpはエラーになりませんでした。

start_time = datetime(2024,11,15,17,59,59,950000)

過去時刻のため、この先のsleepは必ずエラーになりますが。

0Like

Comments

  1. @souripresident

    Questioner

    すみません、この時刻はあくまで一例でこれを実行した時は未来の時刻となってます。間違えて過去の時刻を設定してしまった時は実行した瞬間にエラーになるのですが、今回質問しましたエラーは指定した時刻になると表示されます。

  2. 今回質問しましたエラーは指定した時刻になると表示されます。

    エラーとなる行は、print(ntp_client.get_nowtime()) でしょうか?

  3. @souripresident

    Questioner

    もう一人の方が答えてくださったNTPException: No response received from ntp.nict.jp.の部分だと思います。となると解決策はなさそうです、、

SystemExit: Error: No response received from ntp.nict.jp.
なので、普通に、インターネット経路のどこかでudpパケットが落ちたとか、相手が無視したとかになると思いますけど、、

0Like

Comments

  1. @souripresident

    Questioner

    回答ありがとうございます。ということは予期したり予防したりすることはできない感じですよね

Your answer might help someone💌