date_time_period示例boost :: locale :: period :: first_day_of_week(int v) [英] Example of date_time_period boost::locale::period::first_day_of_week(int v)

查看:170
本文介绍了date_time_period示例boost :: locale :: period :: first_day_of_week(int v)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

boost :: locale文档它说:


date_time_period boost :: locale :: period :: first_day_of_week(int v)[inline]



取得date_time_period:星期几,常数,例如美国= 1的星期日,法国星期一= 2


返回 date_time_period 的函数可用于创建自定义 boost :: locale :: date_time 对象。



我试图创建一个 std :: locale 设置为 en_US.UTF-8,因此一周的第一天默认为星期日,然后将其修改为星期一。这里是代码:

  #include< iostream> 
#include< boost / locale.hpp>

int main(){
using namespace boost :: locale;
date_time_period_set s;
generator gen;
std :: locale locale = gen(en_US.UTF-8);
std :: locale :: global(locale);
std :: cout.imbue(locale);
s.add(period :: year(2000));
s.add(period :: month(6));
s.add(period :: day(5));
s.add(period :: hour(9));
s.add(period :: minute(0));
s.add(period :: second(0));
s.add(period :: first_day_of_week(2)); //将星期的第一天设置为星期一
date_time now(s); // should be 2000-07-05 09:00:00,week starts from Monday
std :: cout<<现在< std :: endl;但是,运行程序会导致错误:

$ b <$ p



$ b $ $
$ b

 在抛出'std :: invalid_argument'实例后调用terminate 
what():无效的date_time期型类型

错误来自其ICU后端适配器:

  static UCalendarDateFields to_icu(period :: marks :: period_mark f)
{
使用命名空间period :: marks;

switch(f){
case era:return UCAL_ERA;
case年:return UCAL_YEAR;
case extended_year:return UCAL_EXTENDED_YEAR;
case month:return UCAL_MONTH;
case day:return UCAL_DATE;
case day_of_year:return UCAL_DAY_OF_YEAR;
case day_of_week:return UCAL_DAY_OF_WEEK;
case day_of_week_in_month:return UCAL_DAY_OF_WEEK_IN_MONTH;
case day_of_week_local:return UCAL_DOW_LOCAL;
case小时:return UCAL_HOUR_OF_DAY;
case hour_12:return UCAL_HOUR;
case am_pm:return UCAL_AM_PM;
case minute:return UCAL_MINUTE;
case second:return UCAL_SECOND;
case week_of_year:return UCAL_WEEK_OF_YEAR;
case week_of_month:return UCAL_WEEK_OF_MONTH;
默认值:
throw std :: invalid_argument(日期时间段类型无效);
}
}

first_day_of_week 不可接受。



所以问题是:


  1. 创建一个 boost :: locale :: date_time 对象,并修改星期的第一天?

  2. 如何使用 date_time_period boost :: locale :: period :: first_day_of_week(int v)


    b

    预备:

      std :: locale english = gen(en_US.UTF-8) ; 
    std :: locale french = gen(fr_FR.UTF-8);
    std :: cout.imbue(english); //这一个不重要
    std :: locale :: global(french);

    经过一些(广泛的)测试后,我发现 first_day_of_week date_time 上的实例是:






    •   std :: locale :: global (英语); 
      assert(1 == period :: first_day_of_week(date_time()));

      std :: locale :: global(french);
      assert(2 == period :: first_day_of_week(date_time()));


    • 或: 在建造期间传递的语言环境

        assert(1 == period :: first_day_of_week(date_time(english))); 
      assert(2 == period :: first_day_of_week(date_time(french)));


    • 或: (忽略区域设置)

      传递的 date_time 对象

        date_time edt(english),fdt(french); 
      assert(1 == period :: first_day_of_week(edt));
      edt = date_time(french);
      assert(2 == period :: first_day_of_week(edt));
      fdt = date_time(english);
      assert(1 == period :: first_day_of_week(fdt));


    • 不能从区域设置以外的其他来源设置

        {
      date_time_period_set dtps;
      dtps.add(period :: friday());
      dtps.add(period :: week_of_year(4));
      //无效果
      dtps.add(period :: first_day_of_week(1));

      assert(2 == period :: first_day_of_week(date_time(dtps)));
      }

      {
      date_time dt;
      //无效果:
      dt.set(period :: first_day_of_week(),1);
      assert(2 == period :: first_day_of_week(dt));
      }




    是一个bug,我离开devs。你可以在boost邮件列表上问一下。肯定是令人惊讶的,因为一个 set 接口的存在表明这个属性可以改变。



    实际上,第一个weekday属性 date_time ,而是 locale 的属性,并且在 date_time 上显示为imbued



    完整测试: Live on Coliru

      #include< boost / locale.hpp> 
    #include< iostream>

    int main()
    {
    使用命名空间boost :: locale;
    generator gen;

    std :: locale english = gen(en_US.UTF-8);
    std :: locale french = gen(fr_FR.UTF-8);
    std :: cout.imbue(english); //这一个不重要
    std :: locale :: global(french);

    {
    std :: localale :: global(english);
    assert(1 == period :: first_day_of_week(date_time()));

    std :: locale :: global(french);
    assert(2 == period :: first_day_of_week(date_time()));
    }

    {
    assert(1 == period :: first_day_of_week(date_time(english)));
    assert(2 == period :: first_day_of_week(date_time(french)));
    }

    {
    date_time_period_set dtps;
    dtps.add(period :: friday());
    dtps.add(period :: week_of_year(4));
    //无效果
    dtps.add(period :: first_day_of_week(1));

    assert(2 == period :: first_day_of_week(date_time(dtps)));
    }

    {
    date_time dt;
    //无效果:
    dt.set(period :: first_day_of_week(),1);
    assert(2 == period :: first_day_of_week(dt));
    }

    {
    //关联的区域设置被复​​制:
    date_time edt(english),fdt(french);
    assert(1 == period :: first_day_of_week(edt));
    edt = date_time(french);
    assert(2 == period :: first_day_of_week(edt));
    fdt = date_time(english);
    assert(1 == period :: first_day_of_week(fdt));
    }

    std :: cout<< 所有测试通过了\\\
    ;
    }


    In boost::locale document it says:

    date_time_period boost::locale::period::first_day_of_week(int v) [inline]

    Get date_time_period for: First day of week, constant, for example Sunday in US = 1, Monday in France = 2

    Those functions which return date_time_period can be used to create custom boost::locale::date_time objects.

    I tried to create one with std::locale set to "en_US.UTF-8", so the first day of week is default to Sunday, and then modified it to Monday. Here's the code:

    #include <iostream>
    #include <boost/locale.hpp>
    
    int main() {
      using namespace boost::locale;
      date_time_period_set s;
      generator gen;
      std::locale locale = gen("en_US.UTF-8");
      std::locale::global(locale);
      std::cout.imbue(locale);
      s.add(period::year(2000));
      s.add(period::month(6));
      s.add(period::day(5));
      s.add(period::hour(9));
      s.add(period::minute(0));
      s.add(period::second(0));
      s.add(period::first_day_of_week(2));// set the first day of week to Monday
      date_time now(s); // should be 2000-07-05 09:00:00, week starts from Monday
      std::cout << now << std::endl;
    }
    

    However, running the program results to an error:

    terminate called after throwing an instance of 'std::invalid_argument'
    what():  Invalid date_time period type
    

    The error comes from its ICU backend adapter:

      static UCalendarDateFields to_icu(period::marks::period_mark f)
      {
          using namespace period::marks;
    
          switch(f) {
          case era: return UCAL_ERA;
          case year: return UCAL_YEAR;
          case extended_year: return UCAL_EXTENDED_YEAR;
          case month: return UCAL_MONTH;
          case day: return UCAL_DATE;
          case day_of_year: return UCAL_DAY_OF_YEAR;
          case day_of_week: return UCAL_DAY_OF_WEEK;
          case day_of_week_in_month:  return UCAL_DAY_OF_WEEK_IN_MONTH;
          case day_of_week_local: return UCAL_DOW_LOCAL;
          case hour: return UCAL_HOUR_OF_DAY;
          case hour_12: return UCAL_HOUR;
          case am_pm: return UCAL_AM_PM;
          case minute: return UCAL_MINUTE;
          case second: return UCAL_SECOND;
          case week_of_year: return UCAL_WEEK_OF_YEAR;
          case week_of_month: return UCAL_WEEK_OF_MONTH;
          default:
              throw std::invalid_argument("Invalid date_time period type");
          }
      }
    

    first_day_of_week is not acceptable.

    So the questions are:

    1. Can a boost::locale::date_time object be created with modified "the first day of week"? If true, how to do it?
    2. How (or where) to use date_time_period boost::locale::period::first_day_of_week(int v)?

    解决方案

    This seems confusing indeed.

    Preliminaries:

    std::locale english = gen("en_US.UTF-8");
    std::locale french  = gen("fr_FR.UTF-8");
    std::cout.imbue(english); // this one doesn't matter
    std::locale::global(french);
    

    After some (extensive) tests, I figured out that the value for first_day_of_week on a date_time instance is:

    • set from the global locale at the time of the construction

      std::locale::global(english);
      assert(1 == period::first_day_of_week(date_time()));
      
      std::locale::global(french);
      assert(2 == period::first_day_of_week(date_time()));
      

    • or: set from the locale that is passed during construction

      assert(1 == period::first_day_of_week(date_time(english)));
      assert(2 == period::first_day_of_week(date_time(french)));
      

    • or: set from the date_time object that is passed during copy construction (ignoring locale)

      date_time edt(english), fdt(french);
      assert(1 == period::first_day_of_week(edt));
      edt = date_time(french);
      assert(2 == period::first_day_of_week(edt));
      fdt = date_time(english);
      assert(1 == period::first_day_of_week(fdt));
      

    • and most importantly: cannot be set from another source than the locale

      {
          date_time_period_set dtps;
          dtps.add(period::friday());
          dtps.add(period::week_of_year(4));
          // no effect
          dtps.add(period::first_day_of_week(1));
      
          assert(2 == period::first_day_of_week(date_time(dtps)));
      }
      
      {
          date_time dt;
          // no effect:
          dt.set(period::first_day_of_week(), 1);
          assert(2 == period::first_day_of_week(dt));
      }
      

    Whether or not this is a bug, I leave up to the devs. You can maybe ask it on the boost mailing list. It sure is surprising, as the presence of a set interface suggests that this property can be changed.

    In fact it appears that the first weekday property is not a property of a date_time in the first place, but rather a property of the locale, and it appears that the locale "imbued" on a date_time instance can not be changed except at construction/assignment.

    Full tests: Live On Coliru

    #include <boost/locale.hpp>
    #include <iostream>
    
    int main()
    {
        using namespace boost::locale;
        generator gen;
    
        std::locale english = gen("en_US.UTF-8");
        std::locale french  = gen("fr_FR.UTF-8");
        std::cout.imbue(english); // this one doesn't matter
        std::locale::global(french);
    
        {
            std::locale::global(english);
            assert(1 == period::first_day_of_week(date_time()));
    
            std::locale::global(french);
            assert(2 == period::first_day_of_week(date_time()));
        }
    
        {
            assert(1 == period::first_day_of_week(date_time(english)));
            assert(2 == period::first_day_of_week(date_time(french)));
        }
    
        {
            date_time_period_set dtps;
            dtps.add(period::friday());
            dtps.add(period::week_of_year(4));
            // no effect
            dtps.add(period::first_day_of_week(1));
    
            assert(2 == period::first_day_of_week(date_time(dtps)));
        }
    
        {
            date_time dt;
            // no effect:
            dt.set(period::first_day_of_week(), 1);
            assert(2 == period::first_day_of_week(dt));
        }
    
        {
            // associated locale gets copied:
            date_time edt(english), fdt(french);
            assert(1 == period::first_day_of_week(edt));
            edt = date_time(french);
            assert(2 == period::first_day_of_week(edt));
            fdt = date_time(english);
            assert(1 == period::first_day_of_week(fdt));
        }
    
        std::cout << "All tests passed\n";
    }
    

    这篇关于date_time_period示例boost :: locale :: period :: first_day_of_week(int v)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆