英文:
Inconsistent behavior for Date.parse() within sveltekit actions (client side vs server side)
问题
I am using a datetime picker from svelte strap (https://sveltestrap.js.org/iframe.html?id=components--inputs&viewMode=story) which outputs a date time string in the form "2023-05-25T20:36", which I was able to tell via binding the value of the date time input to a local variable and console logging it. This is both true within +page.svelte where I print out the variable I am binding the input to, and within the action in +page.server.js. However here is where things get weird: When I call Date.parse() within +page.svelte, this gives me the UTC timestamp I am expecting (assuming 2023-05-25T20:36 is in local time rather than UTC), but when I call Data.parse() on the same string in +page.server.js, it assumes that the string 2023-05-25T20:36 is in UTC time instead of local time and thus gives the wrong timestamp. Is this an issue with my node configuration settings for sveltekit? Why is this weird discrepancy occurring? Please note that my local timezone is MT time (2 hours behind EST, one ahead of California)
Code (+page.svelte):
<Form method="POST">
Set Draft Time!
<Input
type="datetime-local"
name="datetime"
id="exampleDatetime"
placeholder="datetime placeholder"
bind:value={timeStamp}
/>
{timeStamp}
{Date.parse(timeStamp) /* THIS GIVES CORRECT VALUE CORRECTLY ASSUMING THAT timeStamp is in local time instead of UTC time!!}
<button type="submit">Submit Here!</button>
</Form>
+page.server.js
export const actions = {
default: async ({cookies,request,params}) => {
const data = await request.formData();
const dateAsString = data.get("datetime") // This gives the correct local datetime string 2023-05-25T20:36
const timestamp = Date.parse(dateAsString) // This is where the discrepancy is occurring. For some reason, Date.parse() is assuming the input time string is in UTC time instead of local time, and thus the timestamp does not match what I would expect it to.
}
};
英文:
I am using a datetime picker from svelte strap (https://sveltestrap.js.org/iframe.html?id=components--inputs&viewMode=story) which outputs a date time string in the form "2023-05-25T20:36" , which I was able to tell via binding the value of the date time input to a local variable and console logging it. This is both true within +page.svelte where I print out the variable I am binding the input to, and within the action in +page.server.js. However here is where things get weird: When I call Date.parse() within +page.svelte , this gives me the UTC timestamp I am expecting (assuming 2023-05-25T20:36 is in local time rather than UTC), but when I call Data.parse() on the same string in +page.server.js , it assumes that the string 2023-05-25T20:36 is in UTC time instead of local time and thus gives the wrong timestamp. Is this an issue with my node configuration settings for sveltekit? Why is this weird discrepancy occurring? Please note that my local timezone is MT time (2 hours behind EST, one ahead of California)
Code (+page.svelte):
<Form method="POST">
Set Draft Time!
<Input
type="datetime-local"
name="datetime"
id="exampleDatetime"
placeholder="datetime placeholder"
bind:value={timeStamp}
/>
{timeStamp}
{Date.parse(timeStamp) /* THIS GIVES CORRECT VALUE CORRECTLY ASSUMING THAT timeStamp is in local time instead of UTC time!!}
<button type="submit">Submit Here!</button>
</Form>
+page.server.js
export const actions = {
default: async ({cookies,request,params}) => {
const data = await request.formData();
const dateAsString = data.get("datetime") // This gives the correct local datetime string 2023-05-25T20:36
const timestamp = Date.parse(dateAsString) // This is where the discrepancy is occurring. For some reason, Date.parse() is assuming the input time string is in UTC time instead of local time, and thus the timestamp does not match what I would expect it to.
}
};
答案1
得分: 1
时间格式不明确,因此此处未定义实现行为。
该值可能应该被规范化,以便时间部分为 HH:mm:ssZ
表示UTC,或者为本地偏移的 HH:mm:ss+HH:mm
/HH:mm:ss-HH:mm
(请参见日期时间字符串格式)。
英文:
The time format is ambiguous and implementation behavior is thus not defined here.
The value should probably be normalized so the time part is either HH:mm:ssZ
for UTC or HH:mm:ss+HH:mm
/HH:mm:ss-HH:mm
for local offsets. (See date time string format)
答案2
得分: 0
除了接受的答案之外,从浏览器传递正确的时间戳到服务器的另一种方法是使用 sveltekit 文档中所示的 use:enhance 函数:https://kit.svelte.dev/docs/form-actions 。这可以允许您在 formData 中传递自定义值,除了表单提交默认传递的值。这是我最终所做的:
<form
method="POST"
use:enhance={({ data }) => {
data.set("unixTimeStamp",Date.parse(timeStampMillis))
}}>
设置草稿时间!
<Input
type="datetime-local"
name="datetime"
id="exampleDatetime"
bind:value={timeStampMillis}
/>
通过将值 Date.parse(timeStampMillis) 与我们的表单提交一起传递,我们依赖于浏览器对 Date.parse() 的实现,而不是 Node.js 服务器端,因为浏览器正确地假定 timestring "2023-05-25T20:36" 是本地时间。在 +page.server.js 中,我们可以通过以下方式检索已解析的值,而不是 timestring:
export const actions = {
default: async ({cookies,request,params}) => {
console.log("in default action!")
const data = await request.formData();
const dateAsString = data.get("unixTimeStamp")
console.log("unixTimeStamp is:" + dateAsString)
英文:
In addition to the accepted answer, another way to pass the correct timestamp from the browser to the server is using a use:enhance function as shown in the sveltekit docs: https://kit.svelte.dev/docs/form-actions . This can allow you to pass custom values in your formData in addition to the values that the value the form submission passes by default. Here was what I ended up doing:
<form
method="POST"
use:enhance={({ data }) => {
data.set("unixTimeStamp",Date.parse(timeStampMillis))
}}>
Set Draft Time!
<Input
type="datetime-local"
name="datetime"
id="exampleDatetime"
bind:value={timeStampMillis}
/>
By passing the value Date.parse(timeStampMillis) with our form submission, we are relying on the browser's implementation of Date.parse() instead of Node.js server side, as the browser correctly assumes that the timestring "2023-05-25T20:36" is in local time. In the +page.server.js , we can retrieve the parsed value rather than the timestring by using
export const actions = {
default: async ({cookies,request,params}) => {
console.log("in default action!")
const data = await request.formData();
const dateAsString = data.get("unixTimeStamp")
console.log("unixTimeStamp is:" + dateAsString)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论