打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
UTC时间转其他时区时间

UTC时间转其他时区时间

以下代码可以完成UTC时间转其他时区时间,考虑闰年情况,不考虑夏令时情况。时区范围为中时区以西至西十二区,中时区以东至东十四区。

凛冽寒冬,光脚码字,瑟瑟发抖。如有错误,欢迎指出;如有转载,烦请注明。

#include <stdio.h>
#include <string.h>

typedef unsigned char   uint8_t;
typedef unsigned short  uint16_t;
typedef unsigned int    uint32_t;
typedef signed char     int8_t;
typedef signed short    int16_t;
typedef signed int      int32_t;

#define DAYS_PER_WEEK   (7)

#define FALSE_DEF           (0)
#define TRUE_DEF            (1)

#define BIG_MONTH       (1)     /**< 大月份,1、3、5、7、8、10、12月 */
#define LITTLE_MONTH    (2)     /**< 小月份,4、6、9、11月 */
#define FEB_MONTH       (3)     /**< 二月份 */

typedef struct {
    uint32_t year;
    uint8_t month;
    uint8_t date;
    uint8_t hour;
    uint8_t minute;
    uint8_t second;
    uint8_t week;
}TimeStructure;


int32_t isLeapYear(uint32_t year)
{
    if ((year % 400 == 0) ||        (year % 4 == 0 && year % 100 != 0))
    {
        return TRUE_DEF;
    }
    else
    {
        return FALSE_DEF;
    }
}

/**
 * @brief UTC时间转其他时区时间
 *
 * @param utc_time UTC时间
 * @param zone_time 其他时区时间
 * @param time_zone 时区,如东八区为8,西5.5区为-5.5。
 * @return TRUE_DEF 转换成功
 * @return FALSE_DEF 转换失败
 */
int32_t UTCTimeToZoneTime(const TimeStructure *utc_time, TimeStructure *zone_time, double time_zone)
{
    int32_t leap_year_flag = FALSE_DEF; /**< 记录UTC时间下的当前年份是否闰年,是为TRUE_DEF,否为FALSE_DEF */
    int8_t now_month_size  = 0;  /**< 记录UTC时间下的当前月份是大月份(一个月有31天)、小月份(一个月有30天)还是二月份 */
    uint8_t new_week = 0;
    int8_t day_changed = 0;      /**< 用于记录转换时间涉及日期变更与否,为0表示不变更,为-1便是日期减少一天,为1表示日期增加一天 */
    int32_t hour_tmp = 0;
    int32_t minute_tmp = 0;


    /* 参数合理性检查 */
    if (NULL == utc_time || NULL == zone_time)
    {
        printf('\r\n parameter is error! \r\n');
        return FALSE_DEF;
    }

    /* 时区正确性检查,范围为西十二区至东十四区 */
    if (time_zone > 14 || time_zone < -12)
    {
        printf('\r\t time zone is error! \r\n');
        return FALSE_DEF;
    }

    /* 时间格式正确性检查 */
    if ((utc_time->month    > 12) ||        (utc_time->date     > 31) ||        (utc_time->hour     > 23) ||        (utc_time->minute   > 59) ||        (utc_time->second   > 59) ||        (utc_time->week     > 8)
       )
    {
        printf('\r\n utc time is error! \r\n');
        return FALSE_DEF;
    }

    /* 时间格式正确性检查 */
    if ((1  == utc_time->month) ||        (3  == utc_time->month) ||        (5  == utc_time->month) ||        (7  == utc_time->month) ||        (8  == utc_time->month) ||        (10 == utc_time->month) ||        (12 == utc_time->month)
       )
    {
        /* 大月份 */
        now_month_size = BIG_MONTH;
    }
    else if ((4   == utc_time->month) ||             (6   == utc_time->month) ||             (9   == utc_time->month) ||             (11  == utc_time->month)
            )
    {
        /* 小月份 */
        now_month_size = LITTLE_MONTH;
        if (utc_time->date > 30)
        {
            printf('\r\n utc time is error! \r\n');
            return FALSE_DEF;
        }
    }
    else if (2 == utc_time->month)
    {
        /* 二月份 */
        now_month_size = FEB_MONTH;

        /* 判断当前年份是否闰年 */
        leap_year_flag = isLeapYear(utc_time->year);
        if (TRUE_DEF == leap_year_flag)
        {
            if (utc_time->date > 29)
            {
                printf('\r\n utc time is error! \r\n');
                return FALSE_DEF;
            }
        }
        else
        {
            if (utc_time->date > 28)
            {
                printf('\r\n utc time is error! \r\n');
                return FALSE_DEF;
            }
        }
    }
    else
    {
        return FALSE_DEF;
    }

    /* 用0表示周日,用1~6表示周一至周六 */
    if (DAYS_PER_WEEK == utc_time->week)
    {
        new_week = 0;
    }
    else
    {
        new_week = utc_time->week;
    }

    //时间换算
    hour_tmp = utc_time->hour + (int32_t)time_zone;
    minute_tmp = utc_time->minute +  (int)(time_zone * 10) % 10 * 60 / 10;

    if (minute_tmp > 59)
    {
        hour_tmp += 1;
        minute_tmp -= 60;
    }
    else if (minute_tmp < 0)
    {
        hour_tmp -= 1;
        minute_tmp += 60;
    }

    if (hour_tmp > 23)
    {
        day_changed = 1;
        hour_tmp -= 24;
    }
    else if (hour_tmp < 0)
    {
        day_changed = -1;
        hour_tmp += 24;
    }

    memcpy(zone_time, utc_time, sizeof(TimeStructure));

    /* 日期发生改变 */
    if (0 != day_changed)
    {
        /* 大月份 */
        if (BIG_MONTH == now_month_size)
        {
            /* 日期增加,东时区 */
            if (0 < day_changed)
            {
                /* 月末 */
                if (31 == utc_time->date)
                {
                    zone_time->date = 1;
                    /* 十二月,年末 */
                    if (12 == utc_time->month)
                    {
                        zone_time->year += 1;
                        zone_time->month = 1;
                    }
                    else
                    {
                        zone_time->month += 1;
                    }
                }
                else
                {
                    zone_time->date += 1;
                }
            }
            /* 日期减少,西时区 */
            else
            {
                /* 月初 */
                if (1 == utc_time->date)
                {
                    /* 一月份 */
                    if (1 == utc_time->month)
                    {
                        zone_time->date = 31;
                        zone_time->month = 12;
                        zone_time->year -= 1;
                    }
                    /* 三月份 */
                    else if (3 == utc_time->month)
                    {
                        zone_time->month = 2;
                        /* 三月份要考虑闰年问题 */
                        if (TRUE_DEF == leap_year_flag)
                        {
                            zone_time->date = 29;
                        }
                        else
                        {
                            zone_time->date = 28;
                        }
                    }
                    /* 八月份 */
                    else if (8 == utc_time->month)
                    {
                        zone_time->date = 31;
                        zone_time->month -= 1;
                    }
                    /* 其他月份 */
                    else
                    {
                        zone_time->date = 30;
                        zone_time->month -= 1;
                    }
                }
                else
                {
                    zone_time->date -= 1;
                }
            }
        }
        /* 小月份 */
        else if (LITTLE_MONTH == now_month_size)
        {
            /* 日期增加,东时区 */
            if (0 < day_changed)
            {
                /* 月末 */
                if (30 == utc_time->date)
                {
                    zone_time->date = 1;
                    zone_time->month += 1;
                }
                else
                {
                    zone_time->date += 1;
                }
            }
            /* 日期减少,西时区 */
            else
            {
                /* 月初 */
                if (1 == utc_time->date)
                {
                    zone_time->date = 31;
                    zone_time->month -= 1;
                }
                else
                {
                    zone_time->date -= 1;
                }
            }
        }
        /* 二月份 */
        else if (FEB_MONTH == now_month_size)
        {
            /* 日期增加,东时区 */
            if (0 < day_changed)
            {
                /* 月末 */
                if ((TRUE_DEF == leap_year_flag && 29 == utc_time->date) ||                     (FALSE_DEF == leap_year_flag && 28 == utc_time->date))
                {
                    zone_time->date = 1;
                    zone_time->month += 1;
                }
                /* 非月末 */
                else
                {
                    zone_time->date += 1;
                }
            }
            /* 日期减少,西时区 */
            else
            {
                /* 月初 */
                if (1 == utc_time->date)
                {
                    zone_time->date = 31;
                    zone_time->month -= 1;
                }
                else
                {
                    zone_time->date -= 1;
                }
            }
        }
        else
        {
            return FALSE_DEF;
        }

        /* 星期的调整 */
        zone_time->week = (new_week + DAYS_PER_WEEK + day_changed ) % DAYS_PER_WEEK;
    }
    else
    {
        /* 日期没有发生改变 */
        /* do nothing */
    }

    zone_time->hour = hour_tmp;
    zone_time->minute = minute_tmp;

    return TRUE_DEF;
}

int32_t main(void)
{
    TimeStructure utc_time = {
        .year = 2020,
        .month = 12,
        .date = 5,
        .hour = 21,
        .minute = 30 ,
        .second = 00,
        .week = 6
    };
    TimeStructure zone_time = {0};
    double time_zone = 8;


    if ( TRUE_DEF == UTCTimeToZoneTime(&utc_time, &zone_time, time_zone))
    {
        printf('\r\n %d-%d-%d %d:%d:%d week: %d\r\n', zone_time.year,
                zone_time.month, zone_time.date, zone_time.hour,
                zone_time.minute, zone_time.second, zone_time.week );
    }
    else
    {
        printf('\r\n failed! \r\n');
    }

    return 0;
}



本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
Every Time Zone 世界時間時區換算、時差查詢工具 | 免費資源網路社群
【C语言】UTC时间转换为北京时间
Linux 时区设置
起跑线并不重要,更重要的是顺应孩子的时区
荐读|一首很火的美国小诗《自己的时区》
“慢养”的孩子性格最好也走得最远
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服