在PHP中将years.months格式的字符串转换为months

Convert years.months formatted string to months in PHP

提问人:Amit Gupta 提问时间:11/2/2023 最后编辑:mickmackusaAmit Gupta 更新时间:11/3/2023 访问量:219

问:

不幸的是,我从客户那里获得了格式不寻常的数据。我期望在单独的列中显示年份和月份,但相反,它以点分隔字符串的形式出现:.[years].[months]

我已将此数据导入MySql数据库,现在需要转换为我将在其上进一步设置一些操作。years.monthsmonths

因此,我想仅在PHP中将年份(小数点后有月份)转换为月份

测试用例:

  • 1.2(1 年零 2 个月)至14
  • 1.0(1 年零 0 个月) 至12

我编写了以下可能有问题的代码,因此我想更正它。

$yearwithdecimal = "1.2";
$yearwithdecimal = (float)$yearwithdecimal;
if (is_float($yearwithdecimal)) {
    $yearsArray = explode(".",$yearwithdecimal);
    $year_months = $yearsArray[0]*12;
    $more_months = $yearsArray[1];
    $total_months = $year_months + $more_months;
}else{
    $total_months = $yearwithdecimal*12;
}
echo $total_months; die;
// Output is 14
PHP 时间 文本解析 的测量单位

评论

4赞 shingo 11/2/2023
你如何表示 1 年零 11 个月?1.11?
4赞 shingo 11/2/2023
这个问题似乎更适合代码审查,但你仍然需要告知你真正想要改进的地方?
5赞 shingo 11/2/2023
如果 1.10 和 1.1 是浮点数,则无法区分。
2赞 brombeer 11/2/2023
恕我直言,这是一种使用小数的奇怪方式。任何地方的人都真的使用这种“格式”吗?
2赞 shingo 11/3/2023
@mickmackusa我投票决定重新开放。

答:

-1赞 Allen Chak 11/2/2023 #1
  1. 将增量值拆分为 2 部分,$incYears 和 $incMonths
  2. 将$incYears转换为月份 ($incYears * 12) 并添加$incMonths
  3. 将月份添加到日期
    function addDecimalYears($fromDate, $increment){
        $segments = explode(".", (string)$increment, 2);
        $incYears = isset($segments[0]) ? $segments[0] : 0;
        $incMonths = isset($segments[1]) ? $segments[1] : 0;

        $months = 12 * (int)$incYears;
        $months += (int)$incMonths;

        $fromDateTimestamp = strtotime($fromDate);
        return date("Y-m-d", strtotime("+" . $months . "month", $fromDateTimestamp));
    }

    echo addDecimalYears("2023-11-02", 1.0) . "\n";
    echo addDecimalYears("2023-11-02", 1.) . "\n";
    echo addDecimalYears("2023-11-02", .12) . "\n";
    echo addDecimalYears("2023-11-02", 1.6) . "\n";
    echo addDecimalYears("2023-11-02", .18) . "\n";
    echo addDecimalYears("2023-11-02", 0.6) . "\n";

输出:

2024-11-02
2024-11-02
2024-11-02
2025-05-02
2025-05-02
2024-05-02

评论

0赞 Professor Abronsius 11/2/2023
我不明白这如何真正回答这个问题。
0赞 ADyson 11/2/2023
这似乎没有产生 OP 想要的输出
3赞 LF00 11/2/2023 #2

假设您的字段,第一部分表示年数,第二部分表示月数。

将字段作为字符串,然后将其分解为.

$yearwithdecimal = "1.2";
$months = 0;
if($yearwithdecimal){
    $parts = explode('.', $yearwithdecimal);
    $months = $parts[0]*12 + ($parts[1] ?? 0);
}
echo $months;

演示:https://3v4l.org/VhOfV

-2赞 Webpress 11/2/2023 #3
$yearWithDecimal = 1.2;

$years = floor($yearWithDecimal);
$months = ($yearWithDecimal - $years) * 12;

$totalMonths = ($years * 12) + $months;

echo $totalMonths; // Output is 14.4

评论

0赞 Nigel Ren 11/2/2023
我已经检查过了,它似乎打印了 14.4?!
0赞 mickmackusa 11/2/2023
@NigelRen那么,为什么这个无法解释的答案没有投反对票呢?
3赞 Nigel Ren 11/2/2023
@mickmackusa这取决于我如何处理我的选票——如果它被当作“为什么”,我会忽略它——但对我来说——听起来好像你在说我做错了什么。
1赞 mickmackusa 11/2/2023
这是一个错失的策展机会。该系统为其受信任的用户提供了向未来读者发出信号的能力,即哪些内容是“好的”和“不好的”。这个答案显然不好,但你错过了改善所有未来读者体验的机会。系统仍然有时间做正确的事情。当不良内容被点赞时,社区无法将其删除,并浪费了未来读者的时间。如果您不投票删除得分为负的不良内容,那么我也会要求采取适当的行动。
3赞 Nigel Ren 11/2/2023
@mickmackusa SO 不是一个系统,人们可以以不同的方式进行策划 - 发表评论(恕我直言)说答案不正确比任何数量的反对票都要好。你应该按照你认为合适的方式行事,但请给其他人做同样的事情的机会。
3赞 mickmackusa 11/2/2023 #4

如 PHP 将分钟+秒转换为秒中所示,将格式化/分隔字符串解析为整数类型变量,然后将值增加值乘以。$months$years12

代码:(演示)

$tests = ['1.2', '1.0', '2.11'];

foreach ($tests as $test) {
    sscanf($test, '%d.%d', $years, $months);
    $months += $years * 12;
    echo $months . PHP_EOL;
}

输出:

14
12
35
0赞 Shubham Kumar 11/2/2023 #5
    $yearwithdecimal = "1.2";
$yearwithdecimal = (float)$yearwithdecimal;
if (is_float($yearwithdecimal)) {
    $yearsArray = explode(".",$yearwithdecimal);
    $year_months = $yearsArray[0]*12;

    $more_months = isset($yearsArray[1]) ? $yearsArray[1] : 0; 

     $total_months = $year_months + $more_months;
   }else{
        $total_months = $yearwithdecimal*12;
    }

     echo $total_months;

评论

0赞 ADyson 11/2/2023
如果你花时间解释你的答案,包括你做了什么以及你为什么期望它能解决问题,你很可能会得到更积极的回应。大多数时候,只是转储代码实际上不是很有帮助。另请参阅如何回答。在这种情况下,您可能想强调为什么您认为这比各种已经存在且非常相似的答案不同/更好。谢谢。