Python Could Know Your Holidays No Matter Which Country You Live

📅 发布时间:2026/7/8 12:57:34 👁️ 浏览次数:
Python Could Know Your Holidays No Matter Which Country You Live
原文towardsdatascience.com/python-could-know-your-holidays-no-matter-which-country-you-live-ea0f9ce61719https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/77bd158304ed55e2723ef4160acd917a.png图片由 12019 来自 Pixabay在我们的软件开发和数据分析工作中我们喜欢那些可以精确建模的业务逻辑。然而大多数时候我们都在处理一个由许多不遵循任何模式规则构成的现实世界。最好的例子之一就是公共假日。即使在各个国家的子单位中假日也可能非常不同。如果我们的程序需要处理日期那么我们几乎不可能绕过假日。当然最好的解决方案是在您的后端数据库中创建一个维度表并每年更新它。然而有时我们的程序需要处理大量不同的国家或者如果您的应用程序范围较小存储所有假日到后端数据库可能会有太多的开销。有时我们的应用程序或数据分析环境甚至可能没有后端数据库。在这种情况下“假日”库可以成为我们的救命稻草。它包含了 141 个不同国家的所有假日。此外许多内置的有用技巧使得它非常易于使用。让我在这篇文章中向您介绍这个令人惊叹的库。1. 快速入门https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/26e76d7ffefd37e1454d7075146f6dd3.png图片由 นิธิ วีระสันติ 来自 Pixabay如同往常我们将从安装库开始。正如“假日”库的名字很好地反映了其功能我甚至可以记住它。$ pip install holidays在我们能够使用它之前让我们导入库。此外由于我们将要处理日期我们还需要导入 Python 内置的 DateTime 库。fromdatetimeimportdateimportholidayshttps://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/abe88cfd3896a70f55d3b5f56e0b5e51.png1.1 创建假日对象作为任何用例的第一步我们必须创建一个包含所有假日的对象。因为假日是依赖于国家的它们需要用某些位置如国家名称进行初始化。例如如果我们想创建一个包含所有澳大利亚假日的对象以下代码将完成这个任务。au_holidaysholidays.AU()# is equivelant toau_holidaysholidays.country_holidays(AU)你可能对这个对象里有什么内容感到好奇。实际上并没有多少魔法这个对象的内容是一个字典。我们可以通过访问它的items()属性来检查这一点。au_holidays.items()https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/8e36497fec953665c4698ed21c52c183.png1.2 检查日期是否为假日如上图所示假日对象继承了 Python 字典。因此如果我们想检查一个日期是否是假日它将像将日期作为键一样简单并检查键是否在字典中。date(2024,1,1)inau_holidayshttps://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/f5d55eb34cbfe7b553cecb98663c673b.png如果我们检查的日期不是假日当然它会返回 false。date(2024,1,2)inau_holidayshttps://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/f15b6bf60bc7c953f7c58c8bd403538b.png1.3 不同国家的假日由于我们使用国家名称初始化了假日对象该对象将自动包含该国家的假日。这里有一个简单的例子使用 2024 年农历新年也就是我现在写这篇文章的今天——2 月 10 日。如果我们检查日期是否是澳大利亚的假日当然它不是。date(2024,2,10)inau_holidayshttps://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/8bfdb02c75b42537206c104851c4b4d0.png然而如果我们检查是否是中国假日当然答案是肯定的。date(2024,2,10)inholidays.CN()https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/2ee2884172931dcb6641bdc000c57262.png1.4 使用的一些灵活性你可能会想每次我们都要创建一个像这样date(2024, 1, 1)的 Python 日期对象如果我们处理的是其他类型如字符串这会带来太多的开销。别担心我们也可以使用字符串。2024-02-10inholidays.CN()https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/fb78f4dbb7da4f345c0d0ca19176e4bb.png如果我们想检查日期的假日名称我们也可以使用字符串。au_holidays.get(2024-12-26)https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/9f4a9396e0d75452a43c8c00fab3e167.png不满足于只使用字符串如果你的项目处理 Unix 时间戳你也可以直接使用它。# The timestamp below is 2024-02-101707523200inholidays.CN()https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/48ae0514881e6c7a726350a319040c33.png2. 性能考虑https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/be4f4494fa862f87f604e913cab6659c.png图片由ErikaWittlieb在Pixabay提供我必须强调上述一些示例只是为了方便可能不是性能方面的最佳实践。例如holidays.CN()语句将创建一个假日对象。这肯定需要更多的资源。因此除非我们打算只使用一次否则每次使用都创建一个对象绝对不是一个好主意。让我们写一些代码来证明这一点。我必须强调这个神奇命令只能在 Jupyter Notebook 或 Google Colab 中使用。%%timeit date(2024,2,10)inholidays.CN()https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/582279f1c6fa18ee0ed6d2fbcaaac07d.png如果我们首先创建对象然后反复使用这个对象来检查日期是否是中国假日性能会更好。cn_holidaysholidays.CN()%%timeit date(2024,2,10)incn_holidayshttps://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/bafb32712d408b3d09a494fa5c0ffdbc.png因此性能可能相差 1000 倍。请记住如果可能的话要重用节假日对象。3. 许多其他有用的技巧https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/44670621b3ce6960c1df8146f6ba5529.png图片由Steve Bidmead在Pixabay提供到目前为止我们只介绍了 Holidays 库的基本用法。作为一个综合性的库还有很多详细的功能和技巧可用。我相信它们会给我们带来更多的好处。在本节中让我介绍其中的一些。3.1 一个国家的子区域对于由多个部分组成的许多国家来说拥有不同的节假日是很常见的。美国是一个例子澳大利亚也是如此。例如我们可以添加subdivVIC来创建澳大利亚维多利亚州的节假日对象。同样我们也可以添加subdivNSW来创建新南威尔士州的节假日对象。holidays.AU(subdivVIC,years2024)holidays.AU(subdivNSW,years2024)你也可能意识到在上面的代码中我们可以提供年份让节假日对象获取特定年份的节假日。我们可以通过列出所有日期以及节假日名称来轻松检查差异。我想用特定的方式创建节假日对象的原因是为了便于比较。fordate,nameinsorted(holidays.AU(subdivVIC,years2024).items()):print(date,name)fordate,nameinsorted(holidays.AU(subdivNSW,years2024).items()):print(date,name)在上面的代码中我们使用items()获取字典中的所有节假日。然后我们可以使用sorted()函数按键即日期对节假日进行排序。之后我们从字典中获取date和name并打印出来。结果如下。https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/e7a697c42714031c0cbdb38805fcb130.png如上图所示这两个州的劳动节不同。此外维多利亚州有 Grand Final Day 和 Melbourne Cup这些是仅限当地的公共假日而新南威尔士州有银行假日。3.2 按需扩展年份你可能也注意到在上面的例子中我指定了year2024。然后当我们尝试列出对象中的所有节假日时它确实只列出了 2024 年的节假日。那么其他年份呢这是怎么工作的让我给你展示一下。首先让我们创建一个新的节假日对象并尝试列出其中的所有节假日。我们还可以访问其years属性看看里面有哪些年份。au_holidaysholidays.AU()fordate,nameinsorted(au_holidays.items()):print(date,name)au_holidays.yearshttps://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/c524dcd321b179ff863b99c6dc56d49a.png嗯……根本没打印出任何节假日而且years属性也是一个空集合。怎么会这样这难道意味着对象不起作用吗让我们试一试。测试2024-01-01是否为节假日。2024-01-01inau_holidayshttps://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/835bf8585fedaa3d6d9461c94c2ea92b.png它确实工作了但这有点令人困惑。让我们检查它的years属性并再次列出节假日。上面的代码已经提供了所以我只给出结果。https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/4b4704d6662dca77a20d4389a8182d8d.png现在它有了years属性值为 2024假日对象中也提供了假日信息。那么我们不妨再试一次用 2023 年的新年进行测试然后再尝试那些操作https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/6652e1c7fbad4fb558a59e7fd74b3a63.png现在对象中既有 2023 年和 2024 年以及它们在字典中的所有假日。因此可以理解假日对象可以被当作一个“懒”对象它只有在必要时才会获取假日。在我看来这是一个非常好的设计因为我们不太可能需要多年的假日。这种“懒”对象设计可以节省大量内存并提高性能。如果我们想故意排除其他年份的日期呢是的有一个布尔属性默认为expandTrue。如果我们将其设置为false假日对象将“冻结”到当前的years而不会自动扩展。例如如果我们设置expandFalse并测试 2022 年的圣诞节它将返回False。au_holidays.expandFalse2022-12-25inau_holidayshttps://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/0d6baf86338920da231ace92b464a115.png当然我们可以将其改回expandTrue它将能够再次自动扩展。au_holidays.expandTrue2022-12-25inau_holidayshttps://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/b51687da8be048f1373048a8867e8c02.png3.3 多语言支持该库也支持多语言。例如如果我们想用中文显示中文假日我们只需在创建假日对象时指定languagezh_CN。fordt,nameinsorted(holidays.CN(years2024,languagezh_CN).items()):print(dt,name)https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/cba1023d072acd510a043a6cbc19aba3.png3.4 假日组合这又是一个非常有用的功能。例如如果你有一家公司在两个州并且想要同时获取这两个州的假日这就像使用加号来添加两个假日对象一样简单。假设我们想将澳大利亚维多利亚州和新南威尔士州的假日列表合并在一起我们可以这样做。au_holidays_vic_nswholidays.country_holidays(AU,subdivNSW,years2024)holidays.country_holidays(AU,subdivVIC,years2024)au_holidays_vic_nsw.subdivhttps://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/2e27645d9a9e66fb8cb90135dc4769df.png属性subdiv表明这个对象中有两个子分区。然后让我们检查一下假日列表。fordt,nameinsorted(au_holidays_vic_nsw.items()):print(dt,name)https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/92c5c6db67a3355193e7fcbe7d680423.png看现在我们有了两个州的假日列表。摘要https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/8b405b55f54b52558787783bc15a2ed8.png图片由 Julius Silver 来自 Pixabay在这篇文章中我介绍了一个名为holidays的第三方 Python 库。它可以帮助我们从世界上大多数主要国家获取所有公共假日。如果我们不想手动创建包含所有假日的维度表这可能是最好的轻量级解决方案。它不仅能告诉我们某个日期是否是某个国家的假日还能提供许多有用的技巧例如特定子分区的假日、扩展到更多年份和多语言支持。希望这对您有所帮助。除非另有说明所有图片均为作者所有