From 63ac1b296e915bbdaaf4fab2b35df22706626916 Mon Sep 17 00:00:00 2001 From: Joshua Ramon Enslin Date: Fri, 3 May 2024 17:42:32 +0200 Subject: [PATCH] Add functions for transferring dates to ints and vice versa --- src/MD_STD.php | 54 +++++++++++++++++++++++++++++++++++++ tests/MD_STD_Test.php | 62 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 116 insertions(+) create mode 100644 tests/MD_STD_Test.php diff --git a/src/MD_STD.php b/src/MD_STD.php index 67edd58..723f07f 100644 --- a/src/MD_STD.php +++ b/src/MD_STD.php @@ -928,4 +928,58 @@ final class MD_STD { return $output; } + + /** + * Transfers a date into an integer. 0000-01-01 > 101; 2001-01-01 > 20010101. + * Needed to store negative dates (BC) in MySQL. + * + * @param string $date Date. + * + * @return integer + */ + public static function date_to_int(string $date):int { + + // Edge case: -0000-01-01 + if (substr($date, 0, 5) === '-0000') { + return -1 * intval(str_replace("-", "", ltrim($date, "0-"))); + } + + return intval(date("Ymd", strtotime($date))); + + } + + /** + * Transfers an integer into a date, reversing the effects of date_to_int. + * 0000-01-01 > 101; 2001-01-01 > 20010101. + * Needed to retrieve negative dates (BC) stored in MySQL. + * + * @param int $date_int Date represented as an integer. + * + * @return string + */ + public static function int_to_date(int $date_int):string { + + $dateStr = (string)$date_int; + + if (substr($dateStr, 0, 1) === '-') { + $isNegative = true; + $dateStr = substr($dateStr, 1); + } + else $isNegative = false; + + if (strlen($dateStr) < 8) { + $dateStr = str_pad($dateStr, 8, "0", STR_PAD_LEFT); + } + + $day = substr($dateStr, -2, 2); + $month = substr($dateStr, -4, 2); + $year = substr($dateStr, -8, 4); + + return match($isNegative) { + true => '-', + false => '', + } . $year . '-' . $month . '-' . $day; + + + } } diff --git a/tests/MD_STD_Test.php b/tests/MD_STD_Test.php new file mode 100644 index 0000000..84c6650 --- /dev/null +++ b/tests/MD_STD_Test.php @@ -0,0 +1,62 @@ + + */ +declare(strict_types = 1); + +use PHPUnit\Framework\TestCase; + +/** + * Tests for MD_STD. + */ +final class MD_STD_Test extends TestCase { + + /** + * Returns sample dates and their equivalent integer values according + * to MD_STD::date_to_int(). + * + * @return array + */ + public static function date_to_int_provider():array { + + $values = [ + ["2022-01-01", 20220101], + ["0022-01-01", 220101], + ["-0022-01-01", -220101], + ["-2022-01-01", -20220101], + ["-0001-01-01", -10101], + ["-0000-01-01", -101], + ["0000-01-01", 101], + ]; + + $output = []; + foreach ($values as $value) { + $output[$value[0]] = $value; + } + return $output; + + } + + /** + * Checks if dates can be translated to int and back. + * + * @dataProvider \MD_STD_Test::date_to_int_provider + * + * @param string $date Date to translate. + * @param integer $expectedInt Expected integer value for it. + * + * @return void + */ + public function test_date_to_int(string $date, int $expectedInt):void { + + $toInt = MD_STD::date_to_int($date); + $toStr = MD_STD::int_to_date($toInt); + + self::assertEquals($expectedInt, $toInt); + self::assertEquals($date, $toStr); + + } + +}