日期时间库(1)-时长

类模版std::chrono::duration表示时间间隔,它由 Rep 类型的计次数和计次周期组成,其中计次周期是一个编译期有理数,表示从一个计次到下一个计次的秒数。Rep可以是整数类型,也可以是浮点数类型。

template<class Rep, class Period = std::ratio<1>> 
class duration;

文章的代码库为:

https://gitee.com/gamestorm577/CppStd

标准库中定义的常用的duration类型有:

nanoseconds  duration<long long, nano>
microseconds duration<long long, micro>
milliseconds duration<long long, milli>
seconds      duration<long long>
minutes      duration<long, ratio<60>>
hours        duration<long, ratio<3600>>
days         duration<int, ratio_multiply<ratio<24>, hours::period>>
weeks        duration<int, ratio_multiply<ratio<7>, days::period>>
years        duration<int, ratio_multiply<ratio<146097, 400>, days::period>>
months       duration<int, ratio_divide<years::period, ratio<12>>>

构造函数

可以通过计次数或者其他的duration来构造新的duration,例如:

std::chrono::hours h1(1);
std::chrono::hours h2(h1);
std::chrono::minutes m(h1);

printf("h1 count = %ld\n", h1.count());
printf("h2 count = %ld\n", h2.count());
printf("m count = %ld\n", m.count());

输出结果为:

h1 count = 1
h2 count = 1
m count = 60

 赋值函数

赋值一个duration给另一个duration,例如:

std::chrono::hours h(5);
std::chrono::minutes m;
m = h;

printf("h count = %ld\n", h.count());
printf("m count = %ld\n", m.count());

输出结果为:

h count = 5
m count = 300

计次数

接口count可以获取duration的计次数,例如:

std::chrono::milliseconds ms(50);
printf("ms count = %lld\n", ms.count());

输出结果为:

ms count = 50

特殊时长

接口zero、min、max可以返回特殊时长的duration,例如:

std::chrono::months zero_duration = std::chrono::months::zero();
printf("zero_duration count of months = %d\n", zero_duration.count());

std::chrono::months min_duration = std::chrono::months::min();
printf("min_duration count of months = %d\n", min_duration.count());

std::chrono::months max_duration = std::chrono::months::max();
printf("max_duration count of months = %d\n", max_duration.count());

输出结果为:

zero_duration count of months = 0
min_duration count of months = -2147483648
max_duration count of months = 2147483647

重载运算符

用于duration的运算和比较。

一元运算符:

printf("test unary plus and unary minus: \n");
std::chrono::seconds s(50);
std::chrono::seconds s_positive = +s;
std::chrono::seconds s_negative = -s;
printf("s_positive val = %lld\n", s_positive.count());
printf("s_negative val = %lld\n", s_negative.count());

输出结果为:

test unary plus and unary minus: 
s_positive val = 50
s_negative val = -50

自增自减运算符:

printf("test increments or decrements: \n");
std::chrono::seconds s(25);
s++;
printf("s val = %lld\n", s.count());
s--;
printf("s val = %lld\n", s.count());

输出结果为:

test increments or decrements: 
s val = 26
s val = 25

二元运算符:

printf("test binary operate: \n");
std::chrono::seconds s(25);
s += std::chrono::seconds(1);
s -= std::chrono::seconds(2);
s *= 2;
s /= 4;
s %= 5;
printf("s val = %lld\n", s.count());

std::chrono::seconds s1(25);
std::chrono::seconds s2(4);
std::chrono::seconds s_res;
s_res = s1 + s2;
printf("s_res val = %lld\n", s_res.count());
s_res = s1 - s2;
printf("s_res val = %lld\n", s_res.count());
s_res = s1 * 5;
printf("s_res val = %lld\n", s_res.count());
s_res = s1 / 5;
printf("s_res val = %lld\n", s_res.count());
s_res = s1 % 4;
printf("s_res val = %lld\n", s_res.count());

输出结果为:

test binary operate: 
s val = 2
s_res val = 29
s_res val = 21
s_res val = 125
s_res val = 5
s_res val = 1

比较运算符:

printf("test compare: \n");
std::chrono::seconds s1(25);
std::chrono::minutes s2(1);
printf("s1 == s2: %d\n", s1 == s2);
printf("s1 != s2: %d\n", s1 != s2);
printf("s1 < s2: %d\n", s1 < s2);
printf("s1 <= s2: %d\n", s1 <= s2);
printf("s1 > s2: %d\n", s1 > s2);
printf("s1 >= s2: %d\n", s1 >= s2);

输出结果为:

test compare: 
s1 == s2: 0
s1 != s2: 1
s1 < s2: 1
s1 <= s2: 1
s1 > s2: 0
s1 >= s2: 0

duration_cast

用于不同类型的duration之间的转换,例如:

std::chrono::years y(2);
std::chrono::months m = std::chrono::duration_cast<std::chrono::months>(y);
printf("%d years = %d months\n", y.count(), m.count());

输出结果为:

2 years = 24 months

取整方式

将一个duration转换为另一个duration时,转换的计次数可能不是整数,floor、ceil和round接口可以控制取整的方式。floor代表向下取整,ceil代表向上取整,round代表就近取整。例如:

using namespace std::chrono_literals;
std::vector<std::chrono::milliseconds> ms_arr = {
    4999ms,  5000ms,  5001ms,  5499ms,  5500ms,  5999ms,
    -4999ms, -5000ms, -5001ms, -5499ms, -5500ms, -5999ms};

printf("Duration\tFloor\tCeil\tRound\n");
printf("(ms)\t\t(sec)\t(sec)\t(sec)\n");
for (auto& ms : ms_arr)
{
    std::chrono::seconds s1 = std::chrono::floor<std::chrono::seconds>(ms);
    std::chrono::seconds s2 = std::chrono::ceil<std::chrono::seconds>(ms);
    std::chrono::seconds s3 = std::chrono::round<std::chrono::seconds>(ms);
    printf("%lld\t\t%lld\t\t%lld\t\t%lld\n", ms.count(), s1.count(),
           s2.count(), s3.count());
}

输出结果为:

Duration	Floor	Ceil	Round
(ms)		(sec)	(sec)	(sec)
4999		4		5		5
5000		5		5		5
5001		5		6		5
5499		5		6		5
5500		5		6		6
5999		5		6		6
-4999		-5		-4		-5
-5000		-5		-5		-5
-5001		-6		-5		-5
-5499		-6		-5		-5
-5500		-6		-5		-6
-5999		-6		-5		-6

绝对值

接口abs获取duration的绝对值,例如:

std::chrono::minutes m(-42);
printf("m count = %ld\n", m.count());
std::chrono::minutes m_abs = std::chrono::abs(m);
printf("m_abs count = %ld\n", m_abs.count());

输出结果为:

m count = -42
m_abs count = 42

字面量

命名空间中 定义了表示duration的字面量,比如

operator""h
operator""min
operator""s
operator""ms
operator""us
operator""ns

代码示例:

using namespace std::literals::chrono_literals;
std::chrono::hours one_day = 24h;
printf("one day is %ld hours\n", one_day.count());

输出结果为:

one day is 24 hours

common_type

两个duration的公共类型,其周期为两个duration的周期的最大公约数,例如:

using type1 = std::chrono::duration<int, std::ratio<20>>;
using type2 = std::chrono::duration<int, std::ratio<15>>;
using common_type = std::common_type<type1, type2>;
common_type::type duration(1);

std::chrono::seconds tmp =
    std::chrono::duration_cast<std::chrono::seconds>(duration);
printf("common_type ratio = %llds\n", tmp.count());

输出结果为:

common_type ratio = 5s

treat_as_floating_point

判断计次类型Rep是否为浮点型,例如:

using namespace std::chrono;

using t1 = treat_as_floating_point<seconds::rep>;
using t2 = treat_as_floating_point<duration<float, seconds::period>::rep>;
using t3 = treat_as_floating_point<duration<double, seconds::period>::rep>;

printf("t1 value = %d\n", t1::value);
printf("t2 value = %d\n", t2::value);
printf("t3 value = %d\n", t3::value);

输出结果为:

t1 value = 0
t2 value = 1
t3 value = 1

duration_values

给出指定计次类型的零值,最大值和最小值,例如:

using duration_value = std::chrono::duration_values<int>;
printf("duration_value zero = %d\n", duration_value::zero());
printf("duration_value min = %d\n", duration_value::min());
printf("duration_value max = %d\n", duration_value::max());

输出结果为:

duration_value zero = 0
duration_value min = -2147483648
duration_value max = 2147483647

hash

todo

格式化formmater

todo

  • 8
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
基于Python可以使用天文学计算Astropy中的sun对象来计算日照时长。sun对象包含了一个get_sun方法,可以获取指定日期、地点的太阳位置。通过计算太阳在某段时间内的位置变化,可以得出该时间段内的日照时长。 具体步骤如下: 1. 安装Astropy,可以通过pip install astropy命令进行安装。 2. 导入所需要的 ```python from astropy.coordinates import EarthLocation, SkyCoord, AltAz from astropy.time import Time from astropy.sun import sun import astropy.units as u ``` 3. 定义需要计算的地点坐标和日期时间 ```python # 以北京市朝阳区为例,经度116.405,纬度39.905,高度50米 Coords = EarthLocation.from_geodetic(116.405*u.deg, 39.905*u.deg, 50*u.m) # 设置计算日期时间,这里取2022年3月21日 TimeNow = Time('2022-03-21 00:00:00') ``` 4. 计算太阳位置 ```python sun_location = sun.get_sun(TimeNow).transform_to(AltAz(obstime=TimeNow, location=Coords)) ``` 5. 计算日出和日落时刻 ```python # 设置太阳高度阈值,这里取-18°,代表太阳出现后18°高度的时刻为日出时刻 # -18°是一般标准,也可根据标准自己设置,在此适当调整。 h0 = -18*u.deg # 计算日出和日落时刻 rise_time, set_time = sun_location.sun_rise_set_time(h0) ``` 6. 计算日照时长 ```python # 计算日照时长,单位为秒 duration = set_time.datetime - rise_time.datetime duration = duration.seconds + duration.microseconds*1e-6 ``` 7. 显示结果 ```python print('日出:%s' % (rise_time.strftime('%H:%M'))) print('日落:%s' % (set_time.strftime('%H:%M'))) print('日照时长为:%.1f小时' % (duration/3600)) ``` 通过以上步骤,就可以用Python根据日照时长计算出指定日期、地点的日出、日落时间和日照时长

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值