Perl 计算两个日期之间开始的天数/周数/月数/年数

Perl 计算两个日期之间开始的天数/周数/月数/年数,perl,datetime,Perl,Datetime,如何计算两个日期之间开始的天数/周数/月数/年数(整数) 日期以历元秒为单位,由函数提供。这些示例显示了根据ISO 8601格式化的时间 1 day begin between 2014-08-24T23:59:59+0200 and 2014-08-25T00:00:01+0200 0 day begins between 2014-08-25T00:00:01+0200 and 2014-08-25T23:59:59+0200 要使用DateTime查找时间戳DT1和DT2之

如何计算两个日期之间开始的天数/周数/月数/年数(整数)

日期以历元秒为单位,由函数提供。这些示例显示了根据ISO 8601格式化的时间

1 day begin  between 2014-08-24T23:59:59+0200 and 2014-08-25T00:00:01+0200   
0 day begins between 2014-08-25T00:00:01+0200 and 2014-08-25T23:59:59+0200   

要使用DateTime查找时间戳DT1和DT2之间的日/周/月/年开始数

  • 查找DT1所属的日期/周/月/年的第一秒的时间戳
  • 查找DT2所属的日期/周/月/年的第一秒的时间戳
  • 找出这两个时间戳之间以天/周/月/年为单位的差异

  • 给予

    给予


    注:

    • 我想在这两个日期之间不会有任何遗漏
    • 较早的时间戳是否在
      $dt1
      $dt2
      中并不重要

    perldoc-q日期
    :呃,什么?你是说你给出的例子与实际数据完全不同吗?你需要定义“两个日期之间开始的日/周/月/年的数量”的含义。如果你只是指浮点值,名义月份是一年的十二分之一,365.2425天,那就可以了。但是人们通常不是这个意思。我想要整数值。@AndrzejA.Filip:好的,那么从1月31日晚上10点到2月1日凌晨2点之间有多少个月?星期天和星期一之间有几周?从2014年12月31日23:59到2015年1月1日00:01之间的几年
    use DateTime qw( );
    
    # Or maybe << time_zone => 'local' >>?
    my $dt1 = DateTime->from_epoch( epoch => ..., time_zone => '+0200' );
    my $dt2 = DateTime->from_epoch( epoch => ..., time_zone => '+0200' );
    
    # Some days in some time zones don't have a midnight, so switch to 'floating'.
    # before truncating. The dts must all be in the same time zone beforehand.
    my $date1 = $dt1->clone;
    my $date2 = $dt2->clone;
    $_->set_time_zone('floating')->truncate( to => 'day' )
       for $date1, $date2;
    
    my $day_starts = $date2->delta_days($date1)->in_units('days');
    
    my $week_starts = do {                   # Sunday starts
       my $date1_week_start = $date1->clone;
       my $date2_week_start = $date2->clone;
    
       $_->subtract( days => $_->day_of_week % 7 )
          for $date1_week_start, $date2_week_start;
    
       $date2_week_start->delta_days($date1_week_start)->in_units('weeks')
    };
    
    my $month_starts = do {
       my $date1_month_start = $date1->clone;
       my $date2_month_start = $date2->clone;
    
       $_->truncate( to => 'month' )
          for $date1_month_start, $date2_month_start;
    
       $date2_month_start->delta_md($date1_month_start)->in_units('months')
    };
    
    my $year_starts = abs( $date2->year - $date1->year );
    
    printf("%d years, %d months, %d weeks and %d days begin between %s and %s\n",
       $year_starts,
       $month_starts,
       $week_starts,
       $day_starts,
       $date1->ymd,
       $date2->ymd,
    );
    
    my $dt1 = DateTime->new( year => 2014, month => 8, day => 23 );
    my $dt2 = DateTime->new( year => 2014, month => 8, day => 24 );
    
    0 years, 0 months, 1 weeks and 1 days begin between 2014-08-23 and 2014-08-24
    
    my $dt1 = DateTime->new( year => 2014, month => 1, day => 31 );
    my $dt2 = DateTime->new( year => 2014, month => 2, day =>  1 );
    
    0 years, 1 months, 0 weeks and 1 days begin between 2014-01-31 and 2014-02-01