每日一题之 hiho235周 润秒(简单模拟)

该博客讨论了计算机系统中闰秒的概念,以及如何在考虑到闰秒的情况下计算两个时间点之间的秒数差异。通过一个具体的例子展示了在2016年底至2017年初的闰秒情况,并提供了简单的模拟计算方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

描述
计算机系统中使用的UTC时间基于原子钟,这种计时方式同“地球自转一周是24小时”的计时方式有微小的偏差。为了弥补这种偏差,我们偶尔需要增加一个“闰秒”。

最近的一次闰秒增加发生在UTC时间2016年的最后一天。我们在2016年12月31日23时59分59秒和2017年1月1日0时0分0秒之间增加了这样一秒:2016年12月31日23时59分60秒,记作2016-12-31 23:59:60。

目前一共增加了27次闰秒,具体添加的时间见下表:

在这里插入图片描述

给出两个时间,请你判断在考虑闰秒的情况下,这两个时间间隔多少秒。

输入
两个时间各占一行,格式是yyyy-MM-dd HH:mm:ss,范围在1970-01-01 00:00:00至2017-03-12 23:59:59之间。保证第一个时间不晚于第二个时间。

输出
两个时间间隔多少秒。

样例输入
2016-12-31 23:59:59
2017-01-01 00:00:00
样例输出
2

思路:

简单模拟,2019了,希望自己更自律一点,更努力一点!

#include <iostream>
#include <climits>
#include <stdio.h>
#include <algorithm>
#include <string>
#include <cstring>
#include <cmath>
#include <vector>
using namespace std;

static int month[12] = {31,28,31,30,31,30,31,31,30,31,30,31};
static int leap_month[12] = {31,29,31,30,31,30,31,31,30,31,30,31};
static long year_second = 31536000;

long count_sec(vector<int> Jun_add, vector<int> Dec_add, int year,int mon,int day,int hour,int min,int sec){
	long result = 0;
	int * m;
	bool leap_Jun = false;
	if((year%400)==0 || (year%4==0 && year%100!=0))
		m = leap_month;
	else
		m = month;
	if(Jun_add[lower_bound(Jun_add.begin(),Jun_add.end(),year)-Jun_add.begin()]==year)
		leap_Jun = true;
	for (int i = 1; i < mon; ++i) {
		result += 86400 * (long)(*(m+(i-1)));
		if(i == 6 && leap_Jun)
			++result;
	}
	result += 86400*(day-1) + 3600*hour + 60*min + sec;

	return result+1;
}

void solve() {
	vector<int> Jun_add(12,0);
	vector<int> Dec_add(17,0);
	int Jun_array[12]  = {1972,1981,1982,1983,1985,1992,1993,1994,1997,2012,2015,3000};
	int Dec_array[17] = {1972,1973,1974,1975,1976,1977,1978,1979,1987,1989,1990,1995,1998,2005,2008,2016,3000};
	for(int i = 0; i < 12; ++i){
		Jun_add[i] = Jun_array[i];
	}
	for(int i = 0; i < 17; ++i){
		Dec_add[i] = Dec_array[i];
	}

	string year1_string, time1_string, year2_string, time2_string;
	cin >> year1_string >> time1_string >> year2_string >> time2_string;
	long long result = 0;

	int year1 = stoi(year1_string.substr(0,4));
	int year2 = stoi(year2_string.substr(0,4));

	auto Jun_index = lower_bound(Jun_add.begin(),Jun_add.end(),year1)-Jun_add.begin(),
	Dec_index = lower_bound(Dec_add.begin(),Dec_add.end(),year1)-Dec_add.begin();
	for (int i = year1;i < year2; ++i) {
		result += year_second;
		if((i%400)==0 || (i%4==0 && i%100!=0)){
			result += 86400;
		}
		if (i == Jun_add[Jun_index]) {
			++result;
			++Jun_index;
		}
		if (i == Dec_add[Dec_index]) {
			++result;
			++Dec_index;
		}

	}

	int month1 = stoi(year1_string.substr(5,2));
	int month2 = stoi(year2_string.substr(5,2));
	int day1 = stoi(year1_string.substr(8,2));
	int day2 = stoi(year2_string.substr(8,2));
	int hour1 = stoi(time1_string.substr(0,2));
	int hour2 = stoi(time2_string.substr(0,2));
	int min1 = stoi(time1_string.substr(3,2));
	int min2 = stoi(time2_string.substr(3,2));
	int sec1 = stoi(time1_string.substr(6,2));
	int sec2 = stoi(time2_string.substr(6,2));
	
	result += count_sec(Jun_add,Dec_add,year2,month2,day2,hour2,min2,sec2);
	result -= count_sec(Jun_add,Dec_add,year1,month1,day1,hour1,min1,sec1);

	cout<<result<<endl;
}


int main() {

	solve();

	return 0;

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值