5.5 例题:时区间时间的转换

问题描述

直到 19世纪,时间校准是一个纯粹的地方现象。每一个村庄当太阳升到昀高点的时候把他们的时钟调到中午 12点。一个钟表制造商人家或者村里主表的时间被认为是官方时间,市民们把自家的钟表和这个时间对齐。每周一些热心的市民会带着时间标准的表,游走大街小巷为其他市民对表。在城市之间旅游的话,在到达新地方的时候需要把怀表校准。但是,当铁路投入使用之后,越来越多的人频繁地长距离地往来,时间变得越来越重要。在铁路的早期,时刻表非常让人迷惑,每一个所谓的停靠时间都是基于停靠地点的当地时间。时间的标准化对于铁路的高效运营变得非常重要。

在 1878年,加拿大人 Sir Sanford Fleming 提议使用一个全球的时区(这个建议被采纳,并衍生了今天我们所使用的全球时区的概念),他建议把世界分成 24个时区,每一个跨越 15度经线(因为地球的经度 360度,划分成 24块后,一块为 15度)。Sir Sanford Fleming的方法解决了一个全球性的时间混乱的问题。

美国铁路公司于 1883年 11月 18日使用了 Fleming 提议的时间方式。 1884年一个国际子午线会议在华盛顿召开,他的目的是选择一个合适的本初子午线。大会昀终选定了格林威治为标准的 0度。尽管时区被确定了下来,但是各个国家并没有立刻更改他们的时间规范,在美国,尽管到 1895年已经有很多州开始使用标准时区时间,国会直到 1918年才强制使用会议制定的时间规范。

今天各个国家使用的是一个 Fleming时区规范的一个变种,中国一共跨越了 5个时区,但是使用了一个统一的时间规范,比 Coordinated Universal Time(UTC,格林威制时间)早 8个小时。俄罗斯也拥护这个时区规范,尽管整个国家使用的时间和标准时区提前了 1个小时。澳大利亚使用 3个时区,其中主时区提前于他按 Fleming规范的时区半小时。很多中东国家也使用了半时时区(即不是按照 Fleming的 24个整数时区)。

因为时区是对经度进行划分,在南极或者北极工作的科学家直接使用了 UTC时间,否则南极大陆将被分解成 24个时区。

时区的转化表如下:

UTC Coordinated Universal Time

GMT Greenwich Mean Time, 定义为 UTC

BST British Summer Time, 定义为 UTC+1 hour

IST Irish Summer Time, 定义为 UTC+1 hour

WET Western Europe Time, 定义为 UTC

WEST Western Europe Summer Time, 定义为 UTC+1 hour

CET Central Europe Time, 定义为 UTC+1

CEST Central Europe Summer Time, 定义为 UTC+2

EET Eastern Europe Time,定义为 UTC+2

EEST Eastern Europe Summer Time, 定义为 UTC+3

MSK Moscow Time, 定义为 UTC+3

MSD Moscow Summer Time, 定义为 UTC+4

AST Atlantic Standard Time, 定义为 UTC-4 hours

ADT Atlantic Daylight Time, 定义为 UTC-3 hours

NST Newfoundland Standard Time, 定义为 UTC-3.5 hours

NDT Newfoundland Daylight Time, 定义为 UTC-2.5 hours

EST Eastern Standard Time, 定义为 UTC-5 hours

EDT Eastern Daylight Saving Time, 定义为 UTC-4 hours

CST Central Standard Time, 定义为 UTC-6 hours

CDT Central Daylight Saving Time, 定义为 UTC-5 hours

MST Mountain Standard Time, 定义为 UTC-7 hours

MDT Mountain Daylight Saving Time, 定义为 UTC-6 hours

PST Pacific Standard Time, 定义为 UTC-8 hours

PDT Pacific Daylight Saving Time, 定义为 UTC-7 hours

HST Hawaiian Standard Time, 定义为 UTC-10 hours

AKST Alaska Standard Time, 定义为 UTC-9 hours

AKDT Alaska Standard Daylight Saving Time, 定义为 UTC-8 hours

AEST Australian Eastern Standard Time, 定义为 UTC+10 hours

AEDT Australian Eastern Daylight Time, 定义为 UTC+11 hours

ACST Australian Central Standard Time, 定义为 UTC+9.5 hours

ACDT Australian Central Daylight Time, 定义为 UTC+10.5 hours

AWST Australian Western Standard Time, 定义为 UTC+8 hours

下面给出了一些时间,请在不同时区之间进行转化。输入数据输入的第一行包含了一个整数 N,表示有 N组测试数据。接下来 N行,每一行包

括一个时间和两个时区的缩写,它们之间用空格隔开。时间由标准的 a.m./p.m给出。

midnight表示晚上 12点(12:00 a.m.),noon表示中午 12点(12:00 p.m.)。

输出要求

假设输入行给出的时间是在第一个时区中的标准时间,要求输出这个时间在第二个时区中的标准时间。

输入样例

noon HST CEST

11:29 a.m. EST GMT

6:01 p.m. CST UTC

12:40 p.m. ADT MSK

输出样例

midnight

4:29 p.m.

12:01 a.m.

6:40 p.m.

解题思路

这个题目要求在两个时区之间进行时间的转换。我们根据每个时区与格林威治时间的转换公式可以推算出两个时区之间的差别。问题的解决方法不难想到,只是日期处理类问题具有共同的特点就是输入输出比较麻烦,有一些需要特殊处理的情况,例如转换后多出一天或少了一天的情况需要处理。具体到这个题目来说:输入时,除了一般的时间表示法:时:分

a.m/p.m.之外,要特殊处理 noon和 midnight;在直接通过格林威治时间进行转换后,要判断是否超过一天或减少了一天的情况;在输出时间时,要对 noon和 midnight进行特殊处理。

解决这个问题时,关键的是确定两个时区之间的时差。因为时区是用字符串形式给出的,所以要先将时区对应到该时区与格林威治时间的时差上。有了每个时区与格林威治时间的时差,就可以计算任意两个时区之间的时差。

参考程序

#include <iostream>
#include <string>

int difference(char* zone1, char* zone2){ //计算两个时区之间的时差,以分钟为单位。

char* zone[32]={"UTC",

"GMT","BST","IST","WET","WEST",

"CET","CEST","EET","EEST","MSK",

"MSD","AST","ADT","NST","NDT",

"EST","EDT","CST","CDT","MST",

"MDT","PST","PDT","HST","AKST",

"AKDT","AEST","AEDT","ACST","ACDT",

"AWST"};

float time[32]={0,0,1,1,0,1,1,2,2,3,3,4,-4,-3,-3.5,-2.5,-5,-4,-6,-5,-7,

-6,-8,-7,-10,-9,-8,10,11,9.5,10.5,8};

int i, j;

for (i = 0; strcmp(zone[i], zone1); i++); //找到第一个时区对应的位置

for (j = 0; strcmp(zone[j], zone2); j++); //找到第二个时区对应的位置

return (int)((time[i] - time[j]) * 60); //计算并返回时差,以分钟为单位

}

int main()

{

int nCases;

scanf("%d", &nCases); // 读入测试数据数目

for (int i = 0; i < nCases; i++){ // 对每组输入数据

char time[9]; //输入的时间

int hours, minutes; //转换成整数

scanf("%s", time); //读入时间

switch(time[0]){

case 'n': hours = 12; //输入为 ”noon”

minutes = 0;

break;

case 'm': hours = 0; //输入为 ”midnight”

minutes = 0;

break;

default : sscanf(time, "%d:%d", &hours, &minutes); //输入为时:分

hours %= 12;

scanf("%s", time);  //读入 “a.m.或 p.m.”

if (time[0] == 'p') hours += 12;

}

char timezone1[5], timezone2[5];

scanf("%s%s", timezone1, timezone2); //读入时区

int newTime;  //以分钟为单位

newTime = hours * 60 + minutes + difference(timezone2, timezone1);

if (newTime < 0) newTime += 1440; //提前一天,将负的时间加上一天。

newTime %= 1440;  //如果超过一天,将一天的时间减去。

switch(newTime){

case 0 : printf("midnight\n"); //新时间为凌晨

break;

case 720: printf("noon\n"); //新时间为中午

break;

default : hours = newTime / 60; //新时间的时

minutes = newTime % 60; //新时间的分

if(hours == 0) //凌晨, 分不为 0

printf("12:%02d a.m.\n", minutes);

else if(hours < 12) //上午

printf("%d:%02d a.m.\n", hours, minutes);

else if(hours == 12) //中午, 分不为 0

printf("12:%02d p.m.\n", minutes);

else //下午

printf("%d:%02d p.m.\n", hours%12, minutes);

} // end of switch

} //end of for

system("pause");
return 0;
 } // end of main

实现中常见的问题

问题一:有人在处理时区名称和时差的对应关系时,不会用数组元素及其下标的方法处理,而是用一连串的 if else语句逐一判定,造成代码冗余,增大了出错的机会;

问题二:对特殊时间点的表示有理解上的问题。12:01am表示凌点 1分,12:01pm表示中午 12点 1分;中午输出 noon,凌晨输出 midnight;

问题三:向前走了一天和推后了一天的情况没考虑到。

问题四:大同学将 12小时制换算成 24小时制,然后根据时区关系作时间变换,再由24小时制换算成 12小时制,注意当有半个小时的差别时,分钟的数值的调整昀容易出错。

转载于:https://www.cnblogs.com/qnbs1/articles/1711765.html

程序设计导引及在线实践之时区间时间的转换相关推荐

  1. P1152 时区间时间的转换

    题目描述 直到 19 世纪,时间校准是一个纯粹的地方现象.每一个村庄当太阳升到最高点的时候把他们的时钟调到中午 12 点.一个钟表制造商人家或者村里主表的时间被认为是官方时间,市民们把自家的钟表和这个 ...

  2. 程序设计导引及在线实践_学院经纬计算学院程序设计基础与实验入选首批国家级一流本科课程...

    近日,教育部公布首批国家级一流本科课程认定清单,计算机与计算科学学院颜晖教授负责,张高燕.张泳.王云武.柳俊老师参与的<程序设计基础与实验>入选"线上线下混合式一流课程" ...

  3. 【摘录】《程序设计导引及在线实践》之排列

    问题描述 大家知道,给出正整数n,则1 到n 这n 个数可以构成n!种排列,把这些排列按照从 小到大的顺序(字典顺序)列出,如n=3 时,列出1 2 3,1 3 2,2 1 3,2 3 1,3 1 2 ...

  4. 读书-算法《程序设计导引及在线实践》-简单计算题5:装箱问题

    问题: 问题分析:主要考虑3*3的产品问题,结合实现的代码想一下,或则是想一下再结合代码 编一下代码: #include <stdio.h> void main() {int N, a, ...

  5. c语言程序设计方法及在线实践课后答案,c语言程序设计实践习题参考答案(西南师范大学出版社).doc...

    附录 习题参考答案 ※ 2.4 设计性实验中的(3)小题参考答案 //用户登录程序 #include "stdio.h" #include "string.h" ...

  6. 2014年秋广州华师在线计算机的作业答案,18秋华师《C语言程序设计B》在线作业-4辅导资料...

    18秋华师<C语言程序设计B>在线作业-4辅导资料 (9页) 本资源提供全文预览,点击全文预览即可全文预览,如果喜欢文档就下载吧,查找使用更方便哦! 2.90 积分 18秋华师<C语 ...

  7. [渝粤教育] 西南科技大学 程序设计语言VB 在线考试复习资料(1)

    程序设计语言VB--在线考试复习资料 一.单选题 1.列表项选择后得到的选中索引是指(). A.Value B.ListValue C.Index D.ListIndex 2.为了隐藏一个窗体,所使用 ...

  8. 华师c语言作业,C语言程序设计(华师在线作业)1.doc

    C语言程序设计(华师在线作业)1 本学期作业以附件形式完成1. 完成一个大小写字母自动转换的程序,输入大写字母,程序可以输出小写字母,输入小写字母,可以输出大写字母2. 用三种循环方式实现1-100的 ...

  9. 《C++程序设计:原理与实践》Chapter10练习

    本文为<C++程序设计:原理与实践>第10章的练习题答案,代码是自己写的,可能会存在不少缺陷,但是基本的功能是可以实现的,仅供参考. 题目描述: 1. 编写一个程序来处理平面中的点.首先定 ...

  10. 华师c语言作业,16秋华师《c语言程序设计a》在线作业

    16秋华师<c语言程序设计a>在线作业 奥鹏 17 春 16 秋华师<C 语言程序设计 A>在线作业 一.单选题(共 20 道试题,共 40 分. ) 1. 已知 x=43,c ...

最新文章

  1. 区块链中的基本概念整理
  2. 亮剑:PHP,我的未来不是梦(5)
  3. 一个释放临时表空间的实例
  4. Mysql游标循环遍历
  5. web前端开发之div+css教程精华收集二
  6. 格罗方德起诉台积电侵犯16项专利、影响巨大;中兴通讯与印尼Smartfren展开合作;网传FB开发新通讯应用Threads……...
  7. jsp mysql环境_MySQL在JSP环境下的操作应用
  8. ie8 不支持 position:fixed 的简单解决办法
  9. Spring+Dubbo集成Redis的两种解决方案
  10. 篇章级关系抽取(Doc-RE)论文列表整理
  11. gtest简短,简单易用
  12. MATLAB图像去雾处理
  13. MODULE_AUTHOR 功能
  14. 英特尔无线蓝牙启动服务器,如何在英特尔Edison上部署蓝牙安全网关
  15. el-cascader级联选择器当子节点的children为空数组的话,有bug(前端解决办法)
  16. 常见编码格式(中文编码)
  17. 关于adb指令安装卸载apk的几个常用命令
  18. 什么是启发式算法(heuristic algorithm)?
  19. can和could的用法_can 和 could 用法异同
  20. 论文阅读 [CVPR-2022] BatchFormer: Learning to Explore Sample Relationships for Robust Representation Lea

热门文章

  1. 数据库的海量数据的存储解析
  2. php防止视频资源被下载
  3. linux系统中看视频,怎么在linux里看视频啊?
  4. zufeoj_1257: 神风堂人数 VIJOS-P1041
  5. 0 基础 Java 自学之路(2021年最新版)
  6. 图书管理系统C语言课程设计
  7. Java如何快速入门?Java基础_Java入门
  8. python简单代码表白-表白python代码
  9. CentOS7环境下MySQL升级
  10. 【Hack The Box】windows练习-- Conceal