前后端数据格式转换:日期字符串到时间戳的最佳实践

前后端数据格式转换:日期字符串到时间戳的最佳实践

在开发过程中,前端与后端的数据传输格式可能会有不一致的情况。例如,前端传递的日期通常以字符串形式(如 “2006-9-1”)发送,而后端可能需要将其存储为时间戳(如 Unix 时间戳:1157068800)。

本文将通过一个具体的场景介绍如何实现日期字符串到时间戳的转换。

注意: 这个方法适用于,传递的数据名称一致,但是数据格式不一致的场景
名称不一致可以尝试使用 @JsonProperty("XXXX")

场景描述

背景

一个预约管理系统的后端接口需要接收用户的预约信息。其中,用户的出生日期 birthDate 前端以字符串格式传递(例如:“2006-9-1”),后端需要将其存储为秒级时间戳。

问题

由于 User 对象中的 birthDate 定义为 Long 类型,直接反序列化字符串到时间戳会报错,需要自定义处理逻辑。

解决方案

实现步骤

  1. 使用 @JsonDeserialize 注解:在 User 类中为 birthDate 属性定义自定义反序列化器。
  2. 编写自定义反序列化器:通过 Jackson 提供的 JsonDeserializer 实现日期字符串到时间戳的转换。

代码实现

User
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import lombok.Data;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.ZoneId;

@Data
public class User {
    private Long id; // 编号
    private String name; // 姓名
    
    // 使用 @JsonProperty 注解将前端的 sex 映射到后端的 gender
    @JsonProperty("sex")
    private Integer gender; // 性别(1男 2女)
    
    // 使用自定义反序列化器将字符串转换为时间戳
    @JsonDeserialize(using = DateToTimestampDeserializer.class)
    private Long birthDate; // 出生日期(秒)
}
自定义反序列化器 DateToTimestampDeserializer
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;

import java.io.IOException;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.ZoneId;

public class DateToTimestampDeserializer extends JsonDeserializer<Long> {

    @Override
    public Long deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
        String dateStr = p.getText();
        // 定义日期格式
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        // 转换为 LocalDate
        LocalDate localDate = LocalDate.parse(dateStr, formatter);
        // 转换为时间戳(秒)
        return localDate.atStartOfDay(ZoneId.systemDefault()).toEpochSecond();
    }
}
测试接口

UserController中编写 save 方法,验证数据是否正确转换:

@RestController
@RequestMapping("/wx/user")
public class UserController {
    
    // 保存用户信息
	@PostMapping("/save")
	public Object save(@RequestBody User user) {
	    System.out.println("User: " + user);

	    // TODO: 保存逻辑

	    return "Success";
	}
}

测试输入与输出

前端输入示例

接口URL: http://localhost:8080/wx/
请求类型: Post
Content-Type: multipart/form-data

{
    "name": "test用户",
    "sex": 1,
    "birthDate": "2006-9-1",
}
后端日志输出
User: User(birthDate=1157068800, name=test用户, gender=1)

注意事项

  1. 日期格式匹配:确保前端传递的日期格式与反序列化器中的格式一致(yyyy-MM-dd)。
  2. 时区处理:使用 ZoneId.systemDefault() 确保时间戳符合服务器的时区设置。
  3. 字段校验:可以使用框架(如 Hibernate Validator)对前端传入的字段进行校验。

总结

通过自定义反序列化器,我们可以轻松实现前端日期字符串到后端时间戳的转换,避免数据类型不匹配的问题。这种方式对其他类似的格式转换场景同样适用,例如处理前端的时间字符串或复杂的嵌套结构数据。

### 正确传递时间戳数据格式转换方法 #### 一、时间戳的定义及其常见形式 时间戳通常是指从某个固定时刻(通常是1970年1月1日午夜UTC)起经过的秒数或毫秒数。它是一种标准化的时间表达方式,在跨平台和多语言环境中被广泛使用。 - **秒级时间戳**:表示自Unix纪元以来的秒数。 - **毫秒级时间戳**:表示自Unix纪元以来的毫秒数[^2]。 #### 二、不同编程语言中时间戳转换方法 ##### Python 中的时间戳转换 Python 提供了多种工具来处理时间戳日期之间的相互转换。例如,可以利用 `time` 和 `datetime` 模块完成这一操作: ```python import time # 将时间戳为指定格式的时间字符串 timestamp = 1672531199 formatted_time = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(timestamp)) print(formatted_time) # 输出类似于 '2023-01-01 12:39:59' ``` 对于更复杂的需求,比如 DataFrame 的批量转换,则可借助 Pandas 库中的 `to_datetime` 方法: ```python import pandas as pd data = {'timestamps': [1672531199, 1672617599]} df = pd.DataFrame(data) df['dates'] = pd.to_datetime(df['timestamps'], unit='s') print(df) ``` 上述代码会将整列的时间戳数据一次性转换为易读的日期格式。 ##### JavaScript 中的时间戳转换 JavaScript 可以通过内置对象 Date 来实现时间戳到标准日期格式的变[^3]: ```javascript const timestamp = 1672531199; const dateObj = new Date(timestamp * 1000); // 需要乘以1000因为JS默认单位是毫秒 console.log(dateObj.toLocaleString()); // 显示本地化的日期时间和格式 ``` ##### Go 语言中的时间戳转换 Go 提供了一个灵活的方法用于时间戳字符串化,支持定制化输出格式[^4]: ```go package main import ( "fmt" "time" ) func main() { timestamp := int64(1722657237) timeStr := time.Unix(timestamp, 0).Format("2006-01-02 15:04:05") fmt.Println(timeStr) // 打印类似 "2024-05-08 14:33:57" } ``` #### 三、前后端交互中的时间戳最佳实践 为了确保前后端之间的时间戳能够无缝对接并减少潜在错误,推荐采用统一的标准进行传输和解析。一种常见的做法是在后端设置专门的反序列化逻辑,自动识别来自前端的不同输入类型,并将其规范化为目标时间戳[^5]。 例如,当接收到来自客户端提交的 ISO 8601 格式的日期串时,服务器端应有能力迅速解读并将之映射至内部存储所需的数值型字段上;反之亦然——由服务层产生的任何时间节点都需遵循一致性的编码规则再反馈回去给用户界面展示出来。 --- ####
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值