Open mean-cj opened 6 months ago
Hello,
I'm sorry for that but there is no way to support that.
First, there are legit cases where people doing Carbon::createFromDate($gregorianYear)->addYears($number)
want to add $number
years and expect to obtain a Gregorian date. And so it has to be a valid Gregorian date (either Feb 28th without overflow, or March 1st with overflow), but not February 29th because it does not exist in Gregorian year 2567.
Even if we would like to support that Carbon
would not be able to as it's based on native PHP DateTime
object which is always representing a single point in time with the constraint to be a valid Gregorian and valid in the given timezone.
You're recommended to split units not to handle Buddhist Era values using a Carbon
or DateTime
object:
use Carbon\Carbon;
$gregorianDate = '2024-02-29';
$carbonObject = Carbon::createFromDate($gregorianDate);
$buddhistDate = $carbonObject->addYears(543)->year . $carbonObject->format('-m-d');
echo "AD (Anno Domini): $gregorianDate\n";
echo "BE (Buddhist Era): $buddhistDate\n";
Thanks.
Hi @kylekatarnls
Thank you for your answer.
What do you think ?
Add my method "formatBuddhist()" for Buddhist Era year format nesbot/carbon/src/Carbon/Traits/Converter.php
public function formatBuddhist(string $format): string
{
if (strpos($format, 'o') !== false) {
$format = str_replace('o', '[{1}]', $format);
}
if (strpos($format, 'Y') !== false) {
$format = str_replace('Y', '[{2}]', $format);
}
if (strpos($format, 'y') !== false) {
$format = str_replace('y', '[{3}]', $format);
}
$function = $this->localFormatFunction ?: static::$formatFunction;
if (!$function) {
$format = $this->rawFormat($format);
}
else if (\is_string($function) && method_exists($this, $function)) {
$format = [$this, $function];
$format = $function(...\func_get_args());
}
$timestamp = $this->getTimestamp();
if (strpos($format, '[{1}]') !== false) {
$format = str_replace('[{1}]', (date('o', $timestamp) + 543), $format);
}
if (strpos($format, '[{2}]') !== false) {
$format = str_replace('[{2}]', (date('Y', $timestamp) + 543), $format);
}
if (strpos($format, '[{3}]') !== false) {
$year = (date('y', $timestamp) + 43) % 100;
$format = str_replace('[{3}]', $year, $format);
}
return $format;
}
$parse = Carbon::parse('2024-02-29 10.55.32');
echo $parse->formatBuddhist("Y-m-d H:i:s"); // 2567-02-29 10:55:32
echo $parse->formatBuddhist("d/m/y H:i:s"); // 29/02/67 10:55:32
If you agree, please add both version 2.x , 3.x versions.
Hello,
I'm not sure yet if this should be included into Carbon itself, go into a separate package, or simply be documented as a macro.
I also see few little possible code changes, for instance, it's not useful to step by the timestamp and involve date()
such as in date('o', $timestamp)
you can simply do $this->format('o')
. You can also use the method str_contains
(even if you don't have PHP 8 yet as nesbot/carbon includes the symfony polyfill for it). And maybe all the if
are not even worth it because if you call $format = str_replace('o', '[{1}]', $format);
and that the string does not contain o
it will just do nothing.
Be careful of $year = (date('y', $timestamp) + 43) % 100;
, when it's < 10, you won't have a trailing zero. You'd get 29/02/7
while this format is supposed to give: 29/02/07
, str_pad can be used to add the trailing 0
.
Unfortunately, 2.x is now only receiving bugfixes. New features only comes into 3.x. On the other side, using macro, it would work on any object v2 or v3:
Carbon::macro('formatBuddhist', static function (string $format): string {
$self = self::this();
$format = strtr($format, [
'o' => '[{1}]',
'Y' => '[{2}]',
'y' => '[{3}]',
]);
$function = $self->localFormatFunction ?: static::$formatFunction;
if (!$function) {
$format = $self->rawFormat($format);
} else if (\is_string($function) && method_exists($self, $function)) {
$format = [$self, $function];
$format = $function(...\func_get_args());
}
$buddhistYear = $self->year + 543;
return strtr($format, [
'[{1}]' => $self->format('o') + 543,
'[{2}]' => $buddhistYear,
'[{3}]' => str_pad($buddhistYear % 100, 2, '0', STR_PAD_LEFT),
]);
});
Hello
Thank you so much for everything, suggestion and for your "Carbon" i love it.
The Buddhist calendar is a set of lunisolar calendars primarily used in Tibet, Cambodia, Laos, Myanmar, India, Sri Lanka, Thailand and Vietnam as well as in Malaysia and Singapore and by Chinese populations for religious or official occasions.
https://en.wikipedia.org/wiki/Buddhist_calendar
Actually, I think adding to carbon is also possible. Just a few lines more, or we can separate it into a separate package.
Have a good day, Thanks
Hello,
Convert year "2024-02-29" to Buddhist Era, the result month is incorrect "2567-03-01" https://play.phpsandbox.io/nesbot/carbon/wlJnA5ObQjKQBX89
I encountered an issue with the following code:
Carbon version: 2.72.2 , 3.0.2 PHP version: 7.4.33, 8.2.15
I expected to get:
"2024-02-29" -> "2567-02-29"
Thanks!