• 时间戳 太平洋夏令时间和本地时间相互转换及自定义夏令时


    自定义夏令时及时区转换官网案例不详细,真是脑袋大。。。。。

    时区转换 时间戳转本地时间  太平洋夏令时 PDT PST

    太平洋时间

    在2006年以及之前,美国太平洋时区总是于每年四月第一个星期日深夜二时正将本地时间(UTC−8)转成夏令时间(UTC−7) ,并于十月的最后一个星期日深夜二时正转回本地时间。

    于2007年生效的2005年能源政策法案,决定了美国太平洋时区的夏令时间始于每年三月的第二个星期六深夜二时正,并终于每年十一月的第一个星期日深夜二时正。而加拿大亦跟随美国的夏令时间制度。

    TimeZoneInfo是某个地方时区转换类。通过此类可以进行各时区自定义和转换。

    TimeZoneInfo.AdjustmentRule定义某个地区国家的某个时间段的夏令时,一个国家或地区可能有多个,如上面太平洋时间有两个TimeZoneInfo.AdjustmentRule。
    第一个为从时间戳为零(1年1月1日0时0分0秒)开始,到2006年12月31日止。

    第二个为2007年第一天(2007年1月1日0时0分0秒)到c#计时最大值最后一天

    TimeZoneInfo.TransitionTime为定义某个时间段(如上面从时间戳为零(1年1月1日0时0分0秒)开始,到2006年12月31日止)的夏令时间时间的开始时间和结束时间。通过
    TimeZoneInfo.TransitionTime CreateFloatingDateRule(
      DateTime timeOfDay,
      int month,
      int week,
      DayOfWeek dayOfWeek)方法创建。

    timeOfDay参数的年月日都是从1年1月1日(时间开始的第一天)

    如:

     TimeZoneInfo.TransitionTime startTransitionTow= TimeZoneInfo.TransitionTime.CreateFloatingDateRule(
        new DateTime(1, 1, 1, 2, 0, 0),
        4, 2, DayOfWeek.Sunday);

    此方法创建了一个夏令时开始时间为每年4月第2个(参数2)星期天(参数DayOfWeek.Sunday)一个时间点。

    .net 3.5版本居然不支持TimeZoneInfo.ConvertTime()。只能单独写写方法。

    夏令时相互转换全部代码如下:

    1. using System;
    2. using System.Collections.ObjectModel;
    3. using System.Globalization;
    4. using System.Text;
    5. public class TimeTool
    6. {
    7. static TimeTool()
    8. {
    9. palmer = GetTimeZoneInfoPDTAndPST();;
    10. }
    11. ///
    12. /// 时间戳开始时间
    13. ///
    14. private static DateTime utsTime = new DateTime(1970, 1, 1, 0, 0, 0, kind: DateTimeKind.Utc);
    15. private static TimeZoneInfo palmer;
    16. private static long unit = 10000000;
    17. private static long startTimeStamp = utsTime.Ticks / unit;
    18. private enum WeekOfMonth
    19. {
    20. First = 1,
    21. Second = 2,
    22. Third = 3,
    23. Fourth = 4,
    24. Last = 5,
    25. }
    26. #region net.35以上版本(net.3.5一下版本TimeZoneInfo.Local属性为null不兼容)
    27. ///
    28. /// 通过夏令时或者太平洋标准时间转换到时间戳
    29. ///
    30. ///
    31. ///
    32. public static long GetPDTAndPSTByString(string time)
    33. {
    34. DateTime dateTimeUtc = DateTime.Parse(time);
    35. DateTime PDTOrPST = TimeZoneInfo.ConvertTime(dateTimeUtc, palmer, TimeZoneInfo.Utc);
    36. return (PDTOrPST - utsTime).Ticks / unit;
    37. }
    38. ///
    39. /// 时间戳转换夏令时或者太平洋标准时间
    40. ///
    41. ///
    42. ///
    43. public static DateTime TimeStampToPDTAndPST(long time)
    44. {
    45. DateTime dateTimeUtc = utsTime + new TimeSpan(time * unit);
    46. DateTime PDTOrPST = TimeZoneInfo.ConvertTime(dateTimeUtc, TimeZoneInfo.Utc, palmer);
    47. return PDTOrPST;
    48. }
    49. ///
    50. /// 时间戳转换到本地时间
    51. ///
    52. ///
    53. ///
    54. public static DateTime TimeStampToLocal(long time)
    55. {
    56. DateTime dateTime = utsTime + new TimeSpan(time * unit);
    57. return TimeZoneInfo.ConvertTime(dateTime, TimeZoneInfo.Utc, TimeZoneInfo.Local);
    58. }
    59. ///
    60. /// 太平洋时间转本地时间
    61. ///
    62. ///
    63. ///
    64. public static DateTime PDTAndPSTToLocal(DateTime dateTime)
    65. {
    66. return TimeZoneInfo.ConvertTime(dateTime, palmer, TimeZoneInfo.Local);
    67. }
    68. ///
    69. /// 太平洋时间转时间戳
    70. ///
    71. ///
    72. ///
    73. public static long PDTAndPSTToTimeStamp(DateTime dateTime)
    74. {
    75. DateTime temp = TimeZoneInfo.ConvertTime(dateTime, palmer, TimeZoneInfo.Utc);
    76. return (temp - utsTime).Ticks / unit;
    77. }
    78. ///
    79. /// 本地时间转换太平洋时间
    80. ///
    81. ///
    82. ///
    83. public static DateTime LocalToPDTOrPST(DateTime dateTime)
    84. {
    85. return TimeZoneInfo.ConvertTime(dateTime, TimeZoneInfo.Local, palmer);
    86. }
    87. ///
    88. /// 本地时间转时间戳
    89. ///
    90. ///
    91. ///
    92. public static long LocalToTimeStamp(DateTime dateTime)
    93. {
    94. DateTime temp = TimeZoneInfo.ConvertTime(dateTime, TimeZoneInfo.Local, TimeZoneInfo.Utc);
    95. return (temp - utsTime).Ticks / unit;
    96. }
    97. ///
    98. /// 获取太平洋标准时间或者夏令时间
    99. /// 在2006年以及之前,美国太平洋时区总是于每年四月第一个星期日深夜二时正将本地时间(UTC−8)转成夏令时间(UTC−7) ,并于十月的最后一个星期日深夜二时正转回本地时间。
    100. ///于2007年生效的2005年能源政策法案,决定了美国太平洋时区的夏令时间始于每年三月的第二个星期六深夜二时正,并终于每年十一月的第一个星期日深夜二时正。而加拿大亦跟随美国的夏令时间制度。
    101. ///
    102. ///
    103. public static TimeZoneInfo GetTimeZoneInfoPDTAndPST()
    104. {
    105. TimeSpan delta = new TimeSpan(1, 0, 0);
    106. TimeZoneInfo.AdjustmentRule adjustment;
    107. DateTime startDateTime = new DateTime(1, 1, 1);
    108. DateTime endDateTime = new DateTime(2006, 12, 31);
    109. TimeSpan time = new TimeSpan(0, 2, 0, 0, 0);
    110. adjustment = GetAdjustmentRulePDTAndPST(
    111. startDateTime,
    112. time,
    113. 4,
    114. DayOfWeek.Sunday,
    115. WeekOfMonth.First,
    116. endDateTime,
    117. time,
    118. 10,
    119. DayOfWeek.Sunday,
    120. WeekOfMonth.Last,
    121. delta);
    122. DateTime startDateTimeTow = new DateTime(2007, 1, 1);
    123. DateTime endDateTimeTwo = DateTime.MaxValue.Date;
    124. endDateTimeTwo.AddHours(2);
    125. TimeZoneInfo.AdjustmentRule adjustmentTow = GetAdjustmentRulePDTAndPST(
    126. startDateTimeTow,
    127. time,
    128. 3,
    129. DayOfWeek.Sunday,
    130. WeekOfMonth.Second,
    131. endDateTimeTwo,
    132. time,
    133. 11,
    134. DayOfWeek.Sunday,
    135. WeekOfMonth.First,
    136. delta);
    137. // Create array for adjustment rules
    138. TimeZoneInfo.AdjustmentRule[] adjustments = {adjustment, adjustmentTow};
    139. // Define other custom time zone arguments
    140. string displayName = "(GMT-08:00) Palmer Time";
    141. string standardName = "Palmer Time";
    142. string daylightName = "Palmer Daylight Time";
    143. TimeSpan offset = new TimeSpan(-8, 0, 0);
    144. TimeZoneInfo palmer = TimeZoneInfo.CreateCustomTimeZone(standardName, offset, displayName, standardName,
    145. daylightName, adjustments);
    146. return palmer;
    147. }
    148. ///
    149. /// 获取夏令时时间规则
    150. ///
    151. /// 夏令时的开始时间
    152. /// 夏令时开始月份
    153. /// 夏令时星期几开始
    154. /// 夏令时开始月份第几周
    155. /// 夏令时的结束时间
    156. /// 夏令时结束月份
    157. /// 夏令时星期几结束
    158. /// 夏令时结束月份第几周
    159. /// 夏令时调整时间
    160. ///
    161. private static TimeZoneInfo.AdjustmentRule GetAdjustmentRulePDTAndPST(
    162. DateTime startDateTime,
    163. TimeSpan startTime,
    164. int startMonth,
    165. DayOfWeek startDayOfWeek,
    166. WeekOfMonth startWeekOfMonth,
    167. DateTime endDateTime,
    168. TimeSpan endTime,
    169. int endMonth,
    170. DayOfWeek endDayOfWeek,
    171. WeekOfMonth endWeekOfMonth,
    172. TimeSpan delta)
    173. {
    174. TimeZoneInfo.TransitionTime startTransitionTow, endTransitionTow;
    175. startTransitionTow = TimeZoneInfo.TransitionTime.CreateFloatingDateRule(
    176. new DateTime(1, 1, 1, startTime.Hours, startTime.Minutes, startTime.Seconds),
    177. startMonth, (int) startWeekOfMonth, startDayOfWeek);
    178. endTransitionTow = TimeZoneInfo.TransitionTime.CreateFloatingDateRule(
    179. new DateTime(1, 1, 1, endTime.Hours, endTime.Minutes, endTime.Seconds),
    180. endMonth, (int) endWeekOfMonth, endDayOfWeek);
    181. startDateTime = new DateTime(startDateTime.Year, startDateTime.Month, startDateTime.Day);
    182. endDateTime = new DateTime(endDateTime.Year, endDateTime.Month, endDateTime.Day);
    183. TimeZoneInfo.AdjustmentRule adjustmentTow;
    184. adjustmentTow = TimeZoneInfo.AdjustmentRule.CreateAdjustmentRule(
    185. startDateTime,
    186. endDateTime,
    187. delta,
    188. startTransitionTow,
    189. endTransitionTow);
    190. return adjustmentTow;
    191. }
    192. #endregion
    193. #region net.3.5兼容接口
    194. /// 获取太平洋标准时间或者夏令时间
    195. /// 在2006年以及之前,美国太平洋时区总是于每年四月第一个星期日深夜二时正将本地时间(UTC−8)转成夏令时间(UTC−7) ,并于十月的最后一个星期日深夜二时正转回本地时间。
    196. ///于2007年生效的2005年能源政策法案,决定了美国太平洋时区的夏令时间始于每年三月的第二个星期六深夜二时正,并终于每年十一月的第一个星期日深夜二时正。而加拿大亦跟随美国的夏令时间制度。
    197. struct PDSData
    198. {
    199. ///
    200. /// 下令时区开始时间
    201. ///
    202. public DateTime PDTStart;
    203. ///
    204. /// 夏令时区结束时间
    205. ///
    206. public DateTime PDTPSTEnd;
    207. public bool IsDaylightSavingTime(DateTime dateTime)
    208. {
    209. //dateTime为标准太平洋时间(-8时区),实际夏令时向前推一个小时(-7时区),所以结束时间需要向前推一个小时
    210. return dateTime >= PDTStart && dateTime < PDTPSTEnd.AddHours(-1);
    211. }
    212. ///
    213. /// 通过太平洋夏令时间判断是否在夏令时
    214. ///
    215. ///
    216. ///
    217. public bool IsDaylightSavingTimeByPST(DateTime dateTime)
    218. {
    219. //dateTime为标准太平洋时间(-8时区),实际夏令时向前推一个小时(-7时区),所以结束时间需要向前推一个小时
    220. return dateTime >= PDTStart && dateTime < PDTPSTEnd;
    221. }
    222. public override string ToString()
    223. {
    224. return string.Format("PDTStart:{0} PDTPSTEnd{1} ", PDTStart, PDTPSTEnd);
    225. }
    226. }
    227. ///
    228. /// 时间戳转换太平洋标准时间或者夏令时间
    229. /// 在2006年以及之前,美国太平洋时区总是于每年四月第一个星期日深夜二时正将本地时间(UTC−8)转成夏令时间(UTC−7) ,并于十月的最后一个星期日深夜二时正转回本地时间。
    230. ///于2007年生效的2005年能源政策法案,决定了美国太平洋时区的夏令时间始于每年三月的第二个星期六深夜二时正,并终于每年十一月的第一个星期日深夜二时正。而加拿大亦跟随美国的夏令时间制度。
    231. ///
    232. ///
    233. ///
    234. public static DateTime TimeStampToPDTAndPST3_5(long time)
    235. {
    236. DateTime gmtTime = utsTime.AddSeconds(time);
    237. gmtTime = gmtTime.AddHours(-8);
    238. PDSData pdsData = getDaylightSavingTimeState();
    239. if (pdsData.IsDaylightSavingTime(gmtTime))
    240. {
    241. gmtTime = gmtTime.AddHours(1); //夏令时前推1小时
    242. }
    243. return gmtTime;
    244. }
    245. private static PDSData getDaylightSavingTimeState()
    246. {
    247. PDSData _pdsData = new PDSData
    248. {
    249. PDTStart = getDaylightSavingTime(DateTime.Now.Year, 3, WeekOfMonth.Second, 2),
    250. PDTPSTEnd = getDaylightSavingTime(DateTime.Now.Year, 11, WeekOfMonth.First, 2),
    251. };
    252. return _pdsData;
    253. }
    254. ///
    255. /// 获取夏令时状态时间
    256. ///
    257. ///
    258. ///
    259. ///
    260. ///
    261. ///
    262. private static DateTime getDaylightSavingTime(int year, int month, WeekOfMonth week, int hour)
    263. {
    264. DateTime start;
    265. int dayCount;
    266. if (week == WeekOfMonth.Last)
    267. {
    268. start = new DateTime(year, month + 1, 1, hour, 0, 0);
    269. dayCount = (7 - (int) start.DayOfWeek) % 7 - 7; //通过下一个月1号计算当月月最后一个星期日天数差
    270. }
    271. else
    272. {
    273. start = new DateTime(year, month, 1, hour, 0, 0);
    274. dayCount = (7 - (int) start.DayOfWeek) % 7; //计算当月1号开始的第一个星期日天数差
    275. }
    276. int weekCount = 7 * ((int) week - 1);
    277. start = start.AddDays(dayCount + weekCount);
    278. return start;
    279. }
    280. ///
    281. /// 时间戳转换到本地时间
    282. ///
    283. ///
    284. ///
    285. public static DateTime TimeStampToLocal3_5(long time)
    286. {
    287. DateTime dateTime = utsTime + new TimeSpan(time * unit);
    288. return TimeZone.CurrentTimeZone.ToLocalTime(dateTime);
    289. }
    290. ///
    291. /// 太平洋标准时间或者夏令时间转换时间戳
    292. /// 在2006年以及之前,美国太平洋时区总是于每年四月第一个星期日深夜二时正将本地时间(UTC−8)转成夏令时间(UTC−7) ,并于十月的最后一个星期日深夜二时正转回本地时间。
    293. ///于2007年生效的2005年能源政策法案,决定了美国太平洋时区的夏令时间始于每年三月的第二个星期六深夜二时正,并终于每年十一月的第一个星期日深夜二时正。而加拿大亦跟随美国的夏令时间制度。
    294. ///
    295. ///
    296. ///
    297. public static long PDTAndPSTToTimeStamp3_5(DateTime dateTime)
    298. {
    299. PDSData pdsData = getDaylightSavingTimeState();
    300. if (pdsData.IsDaylightSavingTimeByPST(dateTime))
    301. {
    302. dateTime = dateTime.AddHours(7); //夏令时推1小时
    303. }
    304. else
    305. {
    306. dateTime = dateTime.AddHours(8);
    307. }
    308. return (dateTime - utsTime).Ticks / unit;
    309. }
    310. ///
    311. /// 太平洋时间转本地时间
    312. ///
    313. ///
    314. ///
    315. public static DateTime PDTAndPSTToLocal3_5(DateTime dateTime)
    316. {
    317. long time = PDTAndPSTToTimeStamp3_5(dateTime);
    318. dateTime = utsTime+ new TimeSpan(time*unit);
    319. return TimeZone.CurrentTimeZone.ToLocalTime(dateTime);
    320. }
    321. ///
    322. /// 本地时间转时间戳
    323. ///
    324. ///
    325. ///
    326. public static long LocalToTimeStamp3_5(DateTime dateTime)
    327. {
    328. DateTime temp = TimeZone.CurrentTimeZone.ToUniversalTime(dateTime);
    329. return (temp - utsTime).Ticks / unit;
    330. }
    331. ///
    332. /// 本地时间转换太平洋时间
    333. ///
    334. ///
    335. ///
    336. public static DateTime LocalToPDTOrPST3_5(DateTime dateTime)
    337. {
    338. dateTime = TimeZone.CurrentTimeZone.ToUniversalTime(dateTime);
    339. TimeZoneInfo palmer = GetTimeZoneInfoPDTAndPST();
    340. return TimeZoneInfo.ConvertTimeFromUtc(dateTime, palmer);
    341. }
    342. #endregion
    343. #region 调试代码
    344. public static void ShowStartAndEndDates()
    345. {
    346. ReadOnlyCollection timeZones = TimeZoneInfo.GetSystemTimeZones();
    347. foreach (TimeZoneInfo timeZone in timeZones)
    348. {
    349. if (timeZone.Id == "Pacific Standard Time")
    350. {
    351. Print(timeZone);
    352. }
    353. }
    354. }
    355. public static void Print(TimeZoneInfo timeZone)
    356. {
    357. // Debug.LogError("================" + timeZone.BaseUtcOffset.Hours);
    358. string[] monthNames = CultureInfo.CurrentCulture.DateTimeFormat.MonthNames;
    359. TimeZoneInfo.AdjustmentRule[] adjustments = timeZone.GetAdjustmentRules();
    360. // Display message for time zones with no adjustments
    361. if (adjustments.Length == 0)
    362. {
    363. // Debug.LogErrorFormat("{0} has no adjustment rules", timeZone.StandardName);
    364. }
    365. else
    366. {
    367. // Handle time zones with 1 or 2+ adjustments differently
    368. bool showCount = false;
    369. int ctr = 0;
    370. string spacer = "";
    371. // builder.Append(string.Format("{0} Adjustment rules", timeZone.StandardName));
    372. // Debug.LogErrorFormat("{0} Adjustment rules", timeZone.StandardName);
    373. if (adjustments.Length > 1)
    374. {
    375. showCount = true;
    376. spacer = " ";
    377. }
    378. // Iterate adjustment rules
    379. foreach (TimeZoneInfo.AdjustmentRule adjustment in adjustments)
    380. {
    381. StringBuilder builder = new StringBuilder();
    382. if (showCount)
    383. {
    384. builder.Append(string.Format(" Adjustment rule #{0}", ctr + 1));
    385. //Debug.LogErrorFormat(" Adjustment rule #{0}", ctr + 1);
    386. ctr++;
    387. }
    388. // Display general adjustment information
    389. builder.Append(string.Format("{0} Start Date: {1:D} \n", spacer, adjustment.DateStart));
    390. builder.Append(string.Format("{0} End Date: {1:D} \n", spacer, adjustment.DateEnd));
    391. builder.Append(string.Format("{0} Time Change: {1}:{2:00} hours \n", spacer,
    392. adjustment.DaylightDelta.Hours, adjustment.DaylightDelta.Minutes));
    393. // Debug.LogErrorFormat("{0} Start Date: {1:D}", spacer, adjustment.DateStart);
    394. // Debug.LogErrorFormat("{0} End Date: {1:D}", spacer, adjustment.DateEnd);
    395. // Debug.LogErrorFormat("{0} Time Change: {1}:{2:00} hours", spacer,
    396. // adjustment.DaylightDelta.Hours, adjustment.DaylightDelta.Minutes);
    397. // Get transition start information
    398. TimeZoneInfo.TransitionTime transitionStart = adjustment.DaylightTransitionStart;
    399. //Debug.LogErrorFormat("{0} Annual Start: ", spacer);
    400. builder.Append(string.Format("{0} Annual Start: \n", spacer));
    401. if (transitionStart.IsFixedDateRule)
    402. {
    403. builder.Append(string.Format("On {0} {1} at {2:t}",
    404. monthNames[transitionStart.Month - 1],
    405. transitionStart.Day,
    406. transitionStart.TimeOfDay));
    407. // Debug.LogErrorFormat("On {0} {1} at {2:t}",
    408. // monthNames[transitionStart.Month - 1],
    409. // transitionStart.Day,
    410. // transitionStart.TimeOfDay);
    411. }
    412. else
    413. {
    414. builder.Append(string.Format("The year {0} mounth{1} day {2} TimeOfDay{3} DayOfWeek{4} \n",
    415. 1, transitionStart.Month, transitionStart.Day, transitionStart.TimeOfDay,
    416. transitionStart.DayOfWeek));
    417. builder.Append(string.Format("The {0} {1} of {2} at {3:t} \n",
    418. ((WeekOfMonth) transitionStart.Week).ToString(),
    419. transitionStart.DayOfWeek.ToString(),
    420. monthNames[transitionStart.Month - 1],
    421. transitionStart.TimeOfDay));
    422. // Debug.LogErrorFormat("The year {0} mounth{1} day {2} TimeOfDay{3} DayOfWeek{4}",
    423. // 1, transitionStart.Month, transitionStart.Day, transitionStart.TimeOfDay,
    424. // transitionStart.DayOfWeek);
    425. // Debug.LogErrorFormat("The {0} {1} of {2} at {3:t}",
    426. // ((WeekOfMonth) transitionStart.Week).ToString(),
    427. // transitionStart.DayOfWeek.ToString(),
    428. // monthNames[transitionStart.Month - 1],
    429. // transitionStart.TimeOfDay);
    430. }
    431. // Get transition end information
    432. TimeZoneInfo.TransitionTime transitionEnd = adjustment.DaylightTransitionEnd;
    433. builder.Append(string.Format("{0} Annual End: ", spacer));
    434. //Debug.LogErrorFormat("{0} Annual End: ", spacer);
    435. if (transitionEnd.IsFixedDateRule)
    436. {
    437. builder.Append(string.Format("On {0} {1} at {2:t}",
    438. monthNames[transitionEnd.Month - 1],
    439. transitionEnd.Day,
    440. transitionEnd.TimeOfDay));
    441. // Debug.LogErrorFormat("On {0} {1} at {2:t}",
    442. // monthNames[transitionEnd.Month - 1],
    443. // transitionEnd.Day,
    444. // transitionEnd.TimeOfDay);
    445. }
    446. else
    447. {
    448. builder.Append(string.Format("The year {0} mounth{1} day {2} TimeOfDay{3} DayOfWeek{4} \n",
    449. 1, transitionEnd.Month, transitionEnd.Day, transitionEnd.TimeOfDay, transitionEnd.DayOfWeek));
    450. builder.Append(string.Format("The {0} {1} of {2} at {3:t}",
    451. ((WeekOfMonth) transitionEnd.Week).ToString(),
    452. transitionEnd.DayOfWeek.ToString(),
    453. monthNames[transitionEnd.Month - 1],
    454. transitionEnd.TimeOfDay));
    455. //
    456. // Debug.LogErrorFormat("The year {0} mounth{1} day {2} TimeOfDay{3} DayOfWeek{4}",
    457. // 1, transitionEnd.Month, transitionEnd.Day, transitionEnd.TimeOfDay, transitionEnd.DayOfWeek);
    458. // Debug.LogErrorFormat("The {0} {1} of {2} at {3:t}",
    459. // ((WeekOfMonth) transitionEnd.Week).ToString(),
    460. // transitionEnd.DayOfWeek.ToString(),
    461. // monthNames[transitionEnd.Month - 1],
    462. // transitionEnd.TimeOfDay);
    463. }
    464. // Debug.LogError(builder);
    465. }
    466. }
    467. }
    468. #endregion
    469. }

  • 相关阅读:
    HTML世界核心
    算法通关村第一关——链表青铜挑战笔记
    网络安全事件应急演练方案
    2021 GIAC 大前端专场思考总结(下篇)
    3000元口碑好的投影仪推荐哪款?双11口碑好的投影仪推荐当贝NEW D3X
    Java StreamAPI使用
    java项目_第166期ssm多人命题系统_java毕业设计_计算机毕业设计
    python批量修改excel单元格内容
    springboot集成minio,docker部署
    python学习004——zip()函数
  • 原文地址:https://blog.csdn.net/fengya1/article/details/127780192