将棋とプログラミング

将棋の学習記録とプログラミングの創作記録

yukicoder No.652 E869120 and TimeZone

No.652 E869120 and TimeZone - yukicoder

この問題解いてみた。

日本の現在時刻と現地のタイムゾーンが与えられ、現地時間を求める問題。

/***********************************
日本の現在時刻から指定したタイムゾーンの
現地時間を求めるプログラム
入力:時 分 タイムゾーン
出力:現地時間
***********************************/
#include<stdio.h>
#include<stdlib.h>

#define MOJI 13 /* 最大入力文字数 */

int main(){

    char* str;  /* 入力データ */
    char* a;    /* 時 */
    char* b;    /* 分 */
    char* utc;  /* UTCの絶対値 */
    char sym;   /* UTCの符号(+,-) */
    int i = 10; /* 入力文字列のUTCの数値からのカウンタ */
    int j = 0;  /* UTCの絶対値を抽出する為のカウンタ */
    int hour,minutes; /* 入力時刻 時と分 */
    double data;    /* UTC(整数、小数両方を考慮) */ /* 日本と現地の時刻の差*/
    int integer;    /* 日本と現地の時刻の差の整数部分 */
    double decimal; /* 日本と現地の時刻の差の小数部分 */
    int local_hour; /* 現地時間の時 */
    int local_minutes;  /* 現地時間の分 */
    int counter = 0;    /* 時の増減カウンタ(0分を超えた場合と0分を遡った場合) */

    str = (char*)calloc(MOJI+1+1,sizeof(char)); /* 最大文字数(MOJI)+改行コード+終端文字分だけポインタの領域確保*/
    fgets(str,MOJI+1+1,stdin);  /* 標準入力 */

    utc = (char*)calloc(5,sizeof(char));    /* UTCの絶対値用のポインタの領域確保 */
    a = (char*)calloc(3,sizeof(char));  /* 入力データの時(a)用のポインタの領域確保 */
    b = (char*)calloc(3,sizeof(char));  /* 入力データの分(b)用のポインタの領域確保 */

    /* 入力データから時(a)の文字列を読み込み、整数に変換 */
    a[0] = str[0];  
    a[1] = str[1];
    a[2] = '\0';
    hour = atoi(a);

    /* 入力データから分(b)の文字列を読み込み、整数に変換 */
    b[0] = str[3];
    b[1] = str[4];
    b[2] = '\0';
    minutes = atoi(b);

    sym = str[9];   /* UTCの符号を読み込む */

    /* 入力データのUTCの絶対値部分から入力データの末端まで文字列に格納 */
    while( str[i] != '\n' && str[i] != '\0' ){
        utc[j] = str[i];
        i++;
        j++;
    }
    utc[j] = '\0';

    data = atof(utc);    /* UTCの絶対値を小数として保存 */

    if( sym == '-' ) data = 24.0 - data;  /* UTCの符号がマイナスの場合は24時間から引いて調整 */
    data -= 9.0; /* UTCを基準の日本のタイムゾーンの9で引いて差を求める */

    integer = (int)data; /* 日本と現地の時の差(整数部分)を求める */
    decimal = data - (double)((int)data); /* 日本と現地の分の差(小数部分)を求める */

    /* 小数の誤差調整 */
    if( decimal > 0.0 ) decimal += 0.0001;
    if( decimal < 0.0 ) decimal -= 0.0001;

    /* 現在の分に調整を加えて現地時間の分に直す*/
    /* ただし、1周分の周回はまだ考慮していない */
    local_minutes = minutes + (int)(60.0 * decimal);

    if( local_minutes >= 60 ) counter++;    /* 60分を上回ってた場合は時を+1 */
    if( local_minutes < 0 ) counter--;  /* 0分を下回ってた場合は時を-1 */   

    /* 現地時間の分がマイナスになってしまった場合 */
    if( local_minutes < 0 ) local_minutes += 60; /* 60分を足して調整 */

    /* 現地時間の時の計算 */
    /* 日本の時から現地時間の時を求める(hour+integer) */
    /* 分の差による周回を超えた場合、遡った場合を考慮して必要に応じて時を+-1する */

    local_hour = hour + integer + counter;

    /* 現地時間の時がマイナスになってしまった場合 */
    if( local_hour < 0 ) local_hour += 24;  /* 24時間を足して調整 */

    local_hour %= 24;  /* 時は23時までなので超えた場合の調整 */
    local_minutes %= 60;  /* 分は59分までなので超えた場合の調整 */

    printf("%02d:%02d\n",local_hour,local_minutes); /* 現地時間の出力 */

    return 0;

}