andegna / 日历
如果您想将埃塞俄比亚日历转换为任何其他日历系统(如公历),这就是您需要的正确包。顺便说一句,它还支持阿姆哈拉日期格式以及更多。
Requires
- php: >=7.3
- geezify/geezify-php: ^1.2
Requires (Dev)
- phpunit/phpunit: ^9.5
README
如果您想将 埃塞俄比亚日历 转换为任何其他日历系统(如公历),这就是您需要的(经过良好测试、设计精良、质量高的)包。
顺便说一句,它还支持阿姆哈拉日期格式以及更多。
基本用法 🔨 ↑
仅为您提供此包的10,000英尺视图(:airplane:)。
// create a gregorian date using PHP's built-in DateTime class $gregorian = new DateTime('next monday'); // just pass it to Andegna\DateTime constractor and you will get $ethiopian date $ethipic = new Andegna\DateTime($gregorian);
格式化它
// format it // ሰኞ፣ ግንቦት ፯ ቀን (ሥላሴ) 00:00:00 እኩለ፡ሌሊት EAT ፳፻፱ (ማርቆስ) ዓ/ም echo $ethipic->format(Andegna\Constants::DATE_GEEZ_ORTHODOX); // ሰኞ፣ ግንቦት 07 ቀን 00:00:00 እኩለ፡ሌሊት EAT 2009 ዓ/ም echo $ethipic->format(Andegna\Constants::DATE_ETHIOPIAN);
修改它
$ethipic->modify('+8 hours'); $ethipic->sub(new DateInterval('PT30M')); // 30 minutes // ሰኞ, 07-ግን-2009 07:30:00 EAT echo $ethipic->format(DATE_COOKIE);
得到您想要的 😉
echo $ethipic->getYear(); // 2009 echo $ethipic->getMonth(); // 9 echo $ethipic->getDay(); // 7 echo $ethipic->getTimestamp(); // 1494822600 // turn it back to gregorian // Monday, 15-May-2017 07:30:00 EAT echo $ethipic->toGregorian()->format(DATE_COOKIE);
要求 ↑
Andegna 日历需要 php: >=7.0
和火焰与鲜血 🔥 🐉。
请注意,此包的名称为 andegna/calender
而不是 andegna/calendar
。这是一个拼写错误,我没有打算修复。
安装 ↑
Andegna 日历 使用 Composer 来管理其依赖项。因此,在使用之前,请确保您已经在您的计算机上安装了Composer。
Composer 是一个用于PHP依赖项管理的工具。它允许您声明项目依赖的库,并且它会为您管理(安装/更新)它们。
如果您以前从未使用过composer 😳,请在再次编写任何PHP代码之前,请务必阅读这里的一些简介。
composer require andegna/calender
转换 ↑
在我们谈论日历转换之前,我们最好了解一下 Andegna\DateTime
类是如何在内部工作的。
Andegna\DateTime
类只是PHP内置的 DateTime
对象的一个包装,并实现了PHP的 DateTimeInterface
(OK!我在一部分上撒了谎,但请相信我,您不需要知道那个 😄)。
所以 Andegna\DateTime
保留着公历日期,并覆盖了 format
、getTimestamp
、add
、'diff' 以及此类方法,以为您提供埃塞俄比亚日历等效值。
这就是它的基本工作原理。
从埃塞俄比亚日期 ↑
您可以从给定的埃塞俄比亚日期创建一个 Andegna\DateTime
。
让我们“创建”
$millennium = Andegna\DateTimeFactory::of(2000, 1, 1); // ረቡዕ፣ መስከረም 01 ቀን (ልደታ) 00:00:00 እኩለ፡ሌሊት EAT 2000 (ማቴዎስ) ዓ/ም echo $millennium->format(\Andegna\Constants::DATE_ETHIOPIAN_ORTHODOX).PHP_EOL; // Wednesday, 12-Sep-2007 00:00:00 EAT echo $millennium->toGregorian()->format(DATE_COOKIE).PHP_EOL; $fall_of_derg = Andegna\DateTimeFactory::of(1983, 9, 20, 7, 43, 21, new DateTimeZone('Africa/Addis_Ababa')); // ማክሰኞ፣ ግንቦት 20 ቀን (ሕንፅተ) 07:43:21 ጡዋት EAT 1983 (ዮሐንስ) ዓ/ም echo $fall_of_derg->format(\Andegna\Constants::DATE_ETHIOPIAN_ORTHODOX).PHP_EOL; // Tuesday, 28-May-1991 07:43:21 EAT echo $fall_of_derg->toGregorian()->format(DATE_COOKIE).PHP_EOL;
从时间戳 ↑
假设您有一个来自同一地方的时间戳,可能是来自 time()
函数或某些类型的数据库。
您可以通过这种方式获取 Andegna\DateTime
对象
$timestamp = time(); // or some other place ¯\_(ツ)_/¯ $ethipic = Andegna\DateTimeFactory::fromTimestamp($timestamp);
完成啦。你也可以传递一个DateTimeZone
对象
$sheger = new DateTimeZone('Africa/Addis_Ababa'); $ethiopic = Andegna\DateTimeFactory::fromTimestamp($timestamp, $sheger);
从DateTime对象↑
如果你已经有了DateTime
对象,直接给我就好😄
$gregorian = new DateTime('Thu, 11 May 2017 19:01:26 GMT'); $ethiopic = Andegna\DateTimeFactory::fromDateTime($gregorian); // or just pass it through the constractor $ethiopic = new Andegna\DateTime(new DateTime('next sunday'));
从日期字符串↑
这实际上不是这个包的一部分,但可能有人遇到困难。
一般归结为两个选项。你知道日期字符串的格式吗?
如果你知道日期的格式(你很可能知道)你可以创建一个这样的格里历DateTime
// passing the format followed by the date string you got $gregorian1 = DateTime::createFromFormat('j-M-Y', '15-Feb-2009'); $gregorian2 = DateTime::createFromFormat('m-j-Y', '12-31-1999'); $gregorian3 = DateTime::createFromFormat('Y-m-d H:i:s', '2009-02-15 15:16:17');
要找出格式,请查看这个链接或搜索“PHP日期函数”。
但如果你不知道格式,或者不想弄清楚,只需尝试将其传递给DateTime构造函数。它“可能”会找出日期字符串的格式
$gregorian1 = new DateTime('next sunday'); $gregorian2 = new DateTime('yesterday'); $gregorian3 = new DateTime('1999-12-31'); $gregorian4 = new DateTime('2123-12-31 12:34:56'); $gregorian_bad = new DateTime('12-31-1999'); // this one probably fails
从系统时间↑
显然你可以这样做
$gregorian = new DateTime('now'); $ethiopic = Andegna\DateTimeFactory::fromDateTime($gregorian); // but we provided some shortcuts $now1 = \Andegna\DateTimeFactory::now(); $now2 = new DateTime(); // if you wanna specify time zone $sheger = new DateTimeZone('Africa/Addis_Ababa'); $now3 = \Andegna\DateTimeFactory::now($sheger);
到DateTime↑
如果你想得到内部DateTime
对象(也就是转换成格里历)。
// create some Ethiopian date how ever you want $ethiopian_date = \Andegna\DateTimeFactory::now(); // you get a PHP DateTime object to play with $gregorian = $now->toGregorian();
警告:返回的DateTime对象只是一个克隆。因此,对返回对象的更改/修改不会影响埃塞俄比亚日期。
低级转换↑
如果你像我一样是个极客,你可能对日历很感兴趣,因为它包含天文学、数学和历史。
PHP日历转换的工作原理↑
日历扩展提供了一系列函数,用于简化不同日历格式之间的转换(除了埃塞俄比亚)。它基于的中间标准是儒略日计数。儒略日计数是从公元前4713年1月1日起的天数计数。要在日历系统之间进行转换,你必须首先将其转换为儒略日计数,然后转换为所需的日历系统。儒略日计数与儒略历有很大不同!有关儒略日计数的更多信息,请访问」http://www.hermetic.ch/cal_stud/jdn.htm。有关日历系统的更多信息,请访问」http://www.fourmilab.ch/documents/calendar/。本页的摘录包含在这些说明中,并引用在引号中。
这些话直接来自php文档。
因此,我们需要实现两个东西来将埃塞俄比亚日期转换为任何其他日期。
- 将埃塞俄比亚日期转换为儒略日计数
- 将儒略日计数转换为埃塞俄比亚日期
如果你想知道算法,请查看这个链接。
或者查看我在GitHub上的gist这个链接
从JDN↑
use Andegna\Converter\FromJdnConverter; $jdn = 2457886; $converter = new FromJdnConverter($jdn); $day = $converter->getDay(); // 4 $month = $converter->getMonth(); // 9 $year = $converter->getYear(); // 2009
到JDN↑
use Andegna\Converter\ToJdnConverter; $converter = new ToJdnConverter(21,3,1986); echo $jdn = $converter->getJdn(); // 2449322
实际例子↑
现在,有了这些实用的工具,我们可以将埃塞俄比亚日期转换为任何其他日期。
例如,让我们将其转换为犹太历
$et = new Andegna\DateTime(); // ዓርብ, 04-ግን-2009 14:41:00 EAT echo $et->format(DATE_COOKIE); // create a Ethiopian Date `ToJdnConverter` $converter = new Andegna\Converter\ToJdnConverter($et->getDay(), $et->getMonth(), $et->getYear()); // convert it to jdn $jdn = $converter->getJdn(); // use the built-in php function to convert the jdn to the jewish calendar $jewish_date1 = jdtojewish($jdn); // 9/16/5777 echo $jewish_date1; // it also support formating for the return string $jewish_date2 = jdtojewish($jdn, true, CAL_JEWISH_ADD_ALAFIM_GERESH); // convert the return string to utf-8 $jewish_date2 = iconv ('WINDOWS-1255', 'UTF-8', $jewish_date2); // טז אייר ה'תשעז echo $jewish_date2;
例如,让我们将儒略历转换为埃塞俄比亚历
$day = 29; $month = 4; $year = 2017; // get the jdn using the built in php function $jdn = juliantojd($month, $day, $year); // convert the jd to Ethiopian Date $converter = new Andegna\Converter\FromJdnConverter($jdn); // create a `Andegna\DateTime` from the converted date $ethiopic = Andegna\DateTimeFactory::fromConverter($converter); // ዓርብ, 04-ግን-2009 00:00:00 EAT echo $ethiopic->format(DATE_COOKIE); // Friday, 12-May-2017 00:00:00 EAT echo $ethiopic->toGregorian()->format(DATE_COOKIE);
PHP内置支持的日历列表
- 法国共和国历
- 格里历
- 犹太历
- 儒略历
- Unix(我知道你在想什么。它不是一个日历,但它很方便)
点击这里了解更多关于这些日历功能
操作↑
警告↑
DateTime处理器在内部格里历
DateTime
上工作。操作月份和年份可能得到预期的结果。
操作内部日期时间↑
如果你还不了解的话,你可能需要阅读关于DateTimeInterval的内容。
为了给您一个简要概述,DateInterval
实现了ISO 8601持续时间。
持续时间是时间间隔的组成部分,定义了时间间隔中经过的时间量。持续时间以P[n]Y[n]M[n]DT[n]H[n]M[n]S
或P[n]W
的格式表示。
在这些表示中,[n]被替换为[n]之后每个日期和时间元素的值。
不需要前面的零。大写字母P、Y、M、W、D、T、H、M和S是每个日期和时间元素的标识符,不会被替换。
- P是持续时间标识符(对于期间),位于持续时间表示的开始处。
- Y是年份标识符,位于年数的值之后。
- M是月份标识符,位于月数的值之后。
- W是周标识符,位于周数的值之后。
- D是日标识符,位于日数的值之后。
- T是时间标识符,位于表示的时间组件之前。
- H是小时标识符,位于小时数的值之后。
- M是分钟标识符,位于分钟数的值之后。
- S是秒标识符,位于秒数的值之后。
例如,"P3Y6M4DT12H30M5S"表示一个持续时间为“三年,六个月,四天,十二小时,三十分钟和五秒”。
// let's start from today $today = new Andegna\DateTime(); // Adds an amount of days, months, years, hours, minutes and seconds to a DateTime object $tomorrow = $today->add(new DateInterval('P1D')); $after_some_days = $today->add(new DateInterval('P10DT4H')); $after_6_hours = $today->add(new DateInterval('PT6H')); // Subtracts an amount of days, months, years, hours, minutes and seconds from a DateTime object $yesterday = $today->sub(new DateInterval('P1D')); $before_some_days = $today->sub(new DateInterval('P10DT4H')); $before_6_hours = $today->sub(new DateInterval('PT6H')); // Alters the DateTime object $tomorrow = $today->modify('+1 day'); $yesterday = $today->modify('-1 day'); $after_30_minutes = $today->modify('+30 minutes'); $after_30_minutes = $today->modify('next sunday');
如果你想要获取日期之间的差异
$today = new Andegna\DateTime(); $tomorrow = (new Andegna\DateTime())->add(new DateInterval('P1DT2M3S')); $diff = $today->diff($tomorrow); // returns a DateTimeInterval var_dump($diff);
将输出类似以下的内容
object(DateInterval)[9]
...
public 'd' => int 1
public 'h' => int 0
public 'i' => int 2
public 's' => int 3
...
格式化↑
介绍↑
PHP内置的DateTime
类有一个用于格式化日期的format
方法。
在这里了解格式化方法(点击此处)
在这里阅读格式字符(点击此处)
如果你已经阅读过或者了解PHP日期函数的工作方式,你就已经知道格式化是如何工作的了。
$now = new Andegna\DateTime(); // Let's play a game. It's called "Spot the difference" echo $now->format(DATE_COOKIE); // ዓርብ, 04-ግን-2009 02:09:52 EAT echo $now->toGregorian()->format(DATE_COOKIE); // Friday, 12-May-2017 02:09:52 EAT echo $now->format(DATE_ATOM); // 2009-09-04EAT02:09:52+03:00 echo $now->toGregorian()->format(DATE_ATOM); // 2017-05-12T02:09:52+03:00 echo $now->format('F j ቀን Y'); // ግንቦት 4 ቀን 2009 echo $now->toGregorian()->format('F j ቀን Y'); // May 12 ቀን 2017 echo $now->format('H:i:s A'); // 10:09:17 ረፋድ echo $now->toGregorian()->format('H:i:s A'); // 10:09:17 AM
附加字符格式↑
常量↑
我们已经定义了一些方便的常量,按照埃塞俄比亚的惯例来打印 ❤️。
$date = new Andegna\DateTime(); // ዓርብ፣ ግንቦት 04 ቀን 02:35:45 ውደቀት EAT 2009 ዓ/ም echo $date->format(Andegna\Constants::DATE_ETHIOPIAN); $date->modify('+8 hours'); // ዓርብ፣ ግንቦት 04 ቀን (ዮሐንስ) 10:35:45 ረፋድ EAT 2009 (ማርቆስ) ዓ/ም echo $date->format(Andegna\Constants::DATE_ETHIOPIAN_ORTHODOX); $date->modify('+1 year'); // ቅዳሜ፣ ግንቦት ፬ ቀን 10:35:45 ረፋድ EAT ፳፻፲ ዓ/ም echo $date->format(Andegna\Constants::DATE_GEEZ); $date->modify('-3 years')->modify('+1 day'); // ረቡዕ፣ ግንቦት ፭ ቀን (አቦ) 10:35:45 ረፋድ EAT ፳፻፯ (ዮሐንስ) ዓ/ም echo $date->format(Andegna\Constants::DATE_GEEZ_ORTHODOX);
正如你所看到的3D,这些常量都是以DATE_
开头,后面跟着ETHIOPIAN
或GEEZ
。
后面跟着GEEZ
的将返回以古埃塞俄比亚语表示的日期和年份,而ETHIOPIAN
将输出我们埃塞俄比亚人常用的ASCII数字。
最后,如果你追加_ORTHODOX
,你将得到正教日名称和正教年名称。
假日↑
复活节 ↑
计算复活节日期就像射击一个移动的目标。每个人都认为计算复活节日期是不可能的,有些人认为只有深度信仰的人才可能做到,有些人则认为这是由教会决定的。但是计算复活节日期(也称为Computus)并没有那么复杂。
在最简单的情况下,复活节是北半球春分月后的第一个满月之后的第一个星期日。
这听起来很复杂,在古代很难,但在21世纪却不是这样。
如果您想了解它是如何计算的,我将在即将到来的博客上发布。您可以在此期间阅读这个。
让我们看看您如何可以获取特定年份的复活节日期
$easter = new Andegna\Holiday\Easter(); // እሑድ፣ ሚያዝያ 08 ቀን 00:00:00 እኩለ፡ሌሊት EAT 2009 ዓ/ም echo $easter->get(2009)->format(Andegna\Constants::DATE_ETHIOPIAN).PHP_EOL; // or just ... foreach ([2006,2007,2008,2009,2010,2011,2012] as $year) { echo $easter->get($year)->format(Andegna\Constants::DATE_ETHIOPIAN).PHP_EOL; }
将输出
እሑድ፣ ሚያዝያ 12 ቀን 00:00:00 እኩለ፡ሌሊት EAT 2006 ዓ/ም
እሑድ፣ ሚያዝያ 04 ቀን 00:00:00 እኩለ፡ሌሊት EAT 2007 ዓ/ም
እሑድ፣ ሚያዝያ 23 ቀን 00:00:00 እኩለ፡ሌሊት EAT 2008 ዓ/ም
እሑድ፣ ሚያዝያ 08 ቀን 00:00:00 እኩለ፡ሌሊት EAT 2009 ዓ/ም
እሑድ፣ መጋቢት 30 ቀን 00:00:00 እኩለ፡ሌሊት EAT 2010 ዓ/ም
እሑድ፣ ሚያዝያ 20 ቀን 00:00:00 እኩለ፡ሌሊት EAT 2011 ዓ/ም
እሑድ፣ ሚያዝያ 11 ቀን 00:00:00 እኩለ፡ሌሊት EAT 2012 ዓ/ም
验证器 ↑
验证。你可能也需要。
为了检查埃塞俄比亚日期(给定 day
、month
和 year
)是否有效,你需要做以下这些
- 检查
day
是否在1
到30
(包括)之间 - 检查
month
是否在1
到13
(包括)之间 - 如果
month
是13
,则检查day
是否在1
到6
(包括)之间 - 如果
month
是13
并且day
是6
,则检查年份是否为闰年
或者您可以使用我们的验证器
DateValidator
use Andegna\Validator\DateValidator; // true $is_valid1 = (new DateValidator(15,9, 2009))->isValid(); // false $is_valid2 = (new DateValidator(6,13, 2009))->isValid();
LeapYearValidator
use Andegna\Validator\LeapYearValidator; // false $is_valid3 = (new LeapYearValidator(2009))->isValid(); // true $is_valid4 = (new LeapYearValidator(2007))->isValid();
贡献 ↑
Fork it
Create your feature branch (git checkout -b my-new-feature)
Commit your changes (git commit -am 'Add some feature')
Push to the branch (git push origin my-new-feature)
Create new Pull Request