如何在Gleam中为HTTP Header格式化日期?
设置符合HTTP标准的Date响应头
你需要的Date响应头格式为:
Date: <星期缩写>, <日> <月份缩写> <年> <时>:<分>:<秒> GMT
示例:Date: Wed, 21 Oct 2015 07:28:00 GMT
你的当前实现代码如下:
import gleam/http/elli import gleam/http/response.{type Response} import gleam/http/request.{type Request} import gleam/bytes_builder.{type BytesBuilder} import birl // Define a HTTP service // pub fn my_service(_request: Request(t)) -> Response(BytesBuilder) { let body = bytes_builder.from_string("Hello, world!") response.new(200) |> response.prepend_header("content-type", "text/plain") |> response.prepend_header("server", "gleam") |> response.prepend_header("date", birl.to_iso8601(birl.now())) |> response.set_body(body) } pub fn main() { elli.become(my_service, on_port: 8080) }
问题分析
birl.to_iso8601生成的是ISO8601格式的时间字符串(例如2024-05-20T12:34:56Z),不符合HTTP标准要求的Date头格式,需要手动实现时间格式化逻辑。
修改后的代码
import gleam/http/elli import gleam/http/response.{type Response} import gleam/http/request.{type Request} import gleam/bytes_builder.{type BytesBuilder} import birl import gleam/int import gleam/string import gleam/list // 月份缩写列表,对应1-12月 const MONTHS = [ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" ] // 星期缩写列表,对应周日到周六 const WEEKDAYS = [ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" ] // 将时间格式化为HTTP标准的Date格式 fn format_http_date(time: birl.Time) -> String { let utc_dt = birl.to_utc_datetime(time) // 获取星期缩写,默认取周三避免索引越界 let weekday = list.at(WEEKDAYS, utc_dt.weekday) |> string.unwrap("Wed") // 日期补零为两位 let day = int.to_string(utc_dt.day) |> string.pad_left(2, '0') // 月份从0开始索引,取对应缩写 let month = list.at(MONTHS, utc_dt.month - 1) |> string.unwrap("Oct") let year = int.to_string(utc_dt.year) // 时分秒均补零为两位 let hour = int.to_string(utc_dt.hour) |> string.pad_left(2, '0') let minute = int.to_string(utc_dt.minute) |> string.pad_left(2, '0') let second = int.to_string(utc_dt.second) |> string.pad_left(2, '0') // 拼接成最终的Date头字符串 string.concat([ weekday, ", ", day, " ", month, " ", year, " ", hour, ":", minute, ":", second, " GMT" ]) } // HTTP服务实现 pub fn my_service(_request: Request(t)) -> Response(BytesBuilder) { let body = bytes_builder.from_string("Hello, world!") let current_http_date = format_http_date(birl.now()) response.new(200) |> response.prepend_header("content-type", "text/plain") |> response.prepend_header("server", "gleam") |> response.prepend_header("date", current_http_date) |> response.set_body(body) } pub fn main() { elli.become(my_service, on_port: 8080) }
说明
- 定义了
MONTHS和WEEKDAYS常量,对应HTTP日期要求的月份和星期缩写 format_http_date函数将当前时间转换为UTC datetime,提取各时间组件并补零,最终拼接成符合标准的格式- 在服务函数中调用该函数生成
Date头的值,替换原有的ISO8601格式化逻辑
内容的提问来源于stack exchange,提问作者Andy Fleming
相关产品推荐
相关产品推荐

