Guest User

ISO8601 digit significance

a guest
Sep 25th, 2026
39
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.29 KB | None | 0 0
  1. import matplotlib.pyplot as plt
  2. import matplotlib.patches as mpatches
  3. import matplotlib.ticker as ticker
  4. import numpy as np
  5.  
  6. SECONDS_PER_DAY = 86_400
  7. SECONDS_PER_MONTH = 365.25 * 86_400 / 12
  8. SECONDS_PER_YEAR = 365.25 * 86_400
  9.  
  10. D1 = SECONDS_PER_DAY
  11. D10 = 10 * SECONDS_PER_DAY
  12. M1 = SECONDS_PER_MONTH
  13. M10 = 10 * SECONDS_PER_MONTH
  14. Y1 = SECONDS_PER_YEAR
  15. Y10 = 10 * SECONDS_PER_YEAR
  16. Y100 = 100 * SECONDS_PER_YEAR
  17. Y1000 = 1000 * SECONDS_PER_YEAR
  18.  
  19. H1 = 3600
  20. H10 = 10 * 3600
  21. MIN1 = 60
  22. MIN10 = 600
  23. S1 = 1
  24. S10 = 10
  25.  
  26. # Each tuple: (height_in_seconds, display_label, component)
  27. formats = {
  28. "yyyy-mm-dd HH:MM:SS": [
  29. (Y1000, "y\n×1000", "y"),
  30. (Y100, "y\n×100", "y"),
  31. (Y10, "y\n×10", "y"),
  32. (Y1, "y\n×1", "y"),
  33. (M10, "m\n×10", "m"),
  34. (M1, "m\n×1", "m"),
  35. (D10, "d\n×10", "d"),
  36. (D1, "d\n×1", "d"),
  37. (H10, "H\n×10", "h"),
  38. (H1, "H\n×1", "h"),
  39. (MIN10, "M\n×10", "n"),
  40. (MIN1, "M\n×1", "n"),
  41. (S10, "S\n×10", "s"),
  42. (S1, "S\n×1", "s"),
  43. ],
  44. }
  45.  
  46. COLORS = {
  47. "y": "#1D6FA4",
  48. "m": "#1A7A3C",
  49. "d": "#C2530A",
  50. "h": "#7B3FA0",
  51. "n": "#B8860B",
  52. "s": "#B22222",
  53. }
  54.  
  55. def sci_label(v):
  56. if v < 1:
  57. return rf"$10^{{0}}$"
  58. exp = int(np.floor(np.log10(v)))
  59. coeff = v / 10**exp
  60. if abs(coeff - 1.0) < 0.05:
  61. return rf"$10^{{{exp}}}$"
  62. return rf"${coeff:.1f}\times10^{{{exp}}}$"
  63.  
  64. def sci_tick(v, _=None):
  65. if v <= 0:
  66. return ""
  67. exp = int(np.floor(np.log10(v)))
  68. return rf"$10^{{{exp}}}$"
  69.  
  70. fig, axes = plt.subplots(1, 1, figsize=(10, 8))
  71. axes = [axes]
  72. fig.patch.set_facecolor("white")
  73.  
  74. fig.suptitle(
  75. "ISO 8601 digit significance",
  76. fontsize=15, fontweight="bold", color="#111827", y=0.97,
  77. )
  78.  
  79. YMIN, YMAX = 0.5, 1.5e11
  80.  
  81. for ax, (title, bars) in zip(axes, formats.items()):
  82. ax.set_facecolor("#F8FAFC")
  83. ax.spines[:].set_color("#CBD5E1")
  84. ax.tick_params(colors="#1E293B")
  85. ax.yaxis.label.set_color("#1E293B")
  86.  
  87. n = len(bars)
  88. x = np.arange(n)
  89. heights = [b[0] for b in bars]
  90. labels = [b[1] for b in bars]
  91. comps = [b[2] for b in bars]
  92. bar_colors = [COLORS[c] for c in comps]
  93.  
  94. rects = ax.bar(x, heights, color=bar_colors, edgecolor="white",
  95. linewidth=0.8, zorder=3, width=0.65, alpha=0.88)
  96.  
  97. ax.set_yscale("log")
  98. ax.set_ylim(YMIN, YMAX)
  99. ax.set_xticks(x)
  100. ax.set_xticklabels(labels, fontsize=9, color="#1E293B")
  101. ax.set_title(title, fontsize=12, fontweight="bold", color="#111827", pad=10,
  102. fontfamily="monospace")
  103. ax.grid(axis="y", color="#CBD5E1", linewidth=0.6, zorder=0)
  104.  
  105. # Vertical separator between date and time digits
  106. ax.axvline(x=7.5, color="#94A3B8", linewidth=1.2, linestyle="--", zorder=2)
  107.  
  108. for rect, val in zip(rects, heights):
  109. ax.text(
  110. rect.get_x() + rect.get_width() / 2,
  111. val * 2.5,
  112. sci_label(val),
  113. ha="center", va="bottom",
  114. fontsize=8, color="#111827", fontweight="bold",
  115. )
  116.  
  117. ax.yaxis.set_major_formatter(ticker.FuncFormatter(sci_tick))
  118. ax.yaxis.set_minor_locator(ticker.NullLocator())
  119.  
  120. if True:
  121. ax.set_ylabel("Seconds", color="#1E293B", fontsize=11)
  122. ax.set_xlabel("Digit position →", color="#64748B", fontsize=9)
  123.  
  124. patches = [
  125. mpatches.Patch(color=COLORS["y"], alpha=0.88, label="Year digit"),
  126. mpatches.Patch(color=COLORS["m"], alpha=0.88, label="Month digit"),
  127. mpatches.Patch(color=COLORS["d"], alpha=0.88, label="Day digit"),
  128. mpatches.Patch(color=COLORS["h"], alpha=0.88, label="Hour digit"),
  129. mpatches.Patch(color=COLORS["n"], alpha=0.88, label="Minute digit"),
  130. mpatches.Patch(color=COLORS["s"], alpha=0.88, label="Second digit"),
  131. ]
  132. fig.legend(
  133. handles=patches,
  134. loc="lower center",
  135. ncol=6,
  136. fontsize=10,
  137. framealpha=1.0,
  138. labelcolor="#111827",
  139. facecolor="white",
  140. edgecolor="#CBD5E1",
  141. bbox_to_anchor=(0.5, 0.01),
  142. )
  143.  
  144. plt.tight_layout(rect=[0, 0.07, 1, 0.96])
  145. plt.savefig("/workspace/datetime_formats_comparison.png", dpi=150,
  146. bbox_inches="tight", facecolor=fig.get_facecolor())
  147. print("Saved to /workspace/datetime_formats_comparison.png")
  148.  
Advertisement
Add Comment
Please, Sign In to add comment