英文:
How do I make the sveltekit app send the correct date from the server to the client using prisma?
问题
我在我的SvelteKit应用中使用Prisma来获取数据。我有以下模型。来自数据库的所有类型为@db.DateTime
的日期时间返回正确。所有类型为@db.Date
的shift_date
在客户端上减去了一天,但在服务器端没有。数据库的格式是Date
类型,格式为"YYYY-MM-DD"。我的服务器返回shift_date: 2022-03-15T00:00:00.000Z
,但当我在控制台记录客户端的内容时,它显示shift_date: Mon Mar 14 2022 20:00:00 GMT-0
。我很确定客户端只是将日期转换错误。我不确定最好的解决方案。我是否可以在将其发送给客户端之前以某种方式将日期格式化为我的本地时区?否则,在客户端每次使用此日期时,我都需要添加一天,我宁愿不这样做。
我的模型:
model TurnReport {
...
}
model TurnReport_Areas {
...
}
model TurnReport_Attachments {
...
}
我的查询:
export async function load({ params, getClientAddress }) {
...
console.log(allData)
}
服务器控制台日志:
...
客户端控制台日志:
...
英文:
I am using Prisma in my sveltekit app to get my data. I have the model below. All of the datetime of type @db.DateTime from the database are returning correctly. All of the shift_date of type @db.Date are subtracting one day from what is stored in my database on the client side but not the server side. The format of the database is type Date and is in this format "YYYY-MM-DD". My server is returning shift_date: 2022-03-15T00:00:00.000Z but when I console log what the client has it is showing shift_date: Mon Mar 14 2022 20:00:00 GMT-0. I am pretty sure that the client is just converting the date wrong. I am not sure the best solution. Can I somehow format the date to my local timezone before I send it to the client? Otherwise on the client side every time I use this date I will need to add a day which I would rather not do.
My models:
model TurnReport {
entry_id Int @id(map: "PK_TurnReport") @default(autoincrement())
comment String @db.Text
datetime DateTime @db.DateTime
author String? @db.VarChar(100)
area_id Int
shift_date DateTime @db.Date
shift_num Int @db.TinyInt
ip String? @db.VarChar(32)
TurnReport_Attachments TurnReport_Attachments[]
}
model TurnReport_Areas {
area_id Int @id(map: "PK_TurnReport_Areas")
name String @db.VarChar(75)
dept_id Int
enabled Boolean
sort_order Int
has_stars Boolean
TurnReport_Depts TurnReport_Depts @relation(fields: [dept_id], references: [dept_id], onDelete: Cascade, map: "FK_TurnReport_Areas_TurnReport_Depts")
vTurnReport vTurnReport[]
}
model TurnReport_Attachments {
attachment_id Int @id(map: "PK_TurnReport_Attachments") @default(autoincrement())
entry_id Int
file_name String @db.NVarChar(255)
datetime DateTime @db.DateTime
content_type String @db.NVarChar(255)
content_length Int
data_blob Bytes
TurnReport TurnReport @relation(fields: [entry_id], references: [entry_id], onDelete: Cascade)
}
My query:
export async function load({ params, getClientAddress }) {
const allData = await prisma.TurnReport_Depts.findUnique({
where: {
dept_id: parseInt(params.dept)
},
include: {
TurnReport_Areas: {
where: {
dept_id: parseInt(params.dept)
},
include: {
vTurnReport: {
where: {
shift_date: params.date + 'T00:00:00.000Z',
shift_num: parseInt(params.shift)
},
include: {
vTurnReport_Attachments: true
}
}
}
}
}
})
await prisma.$disconnect()
console.log(allData)
The server console log"
entry_id: 467,
comment: '...',
datetime: 2022-03-15T18:51:54.843Z,
author: 'Sam, Tim',
area_id: 140,
shift_date: 2022-03-15T00:00:00.000Z,
shift_num: 1,
ip: '10.39.12.27',
attachment_count: 0,
vTurnReport_Attachments: []
The client console log:
area_id: 140
attachment_count: 0
author: "Sam, Tim"
comment: "..."
datetime: Tue Mar 15 2022 14:51:54 GMT-0400 (Eastern Daylight Time) {}
entry_id: 467
ip: "10.39.12.27"
shift_date: Mon Mar 14 2022 20:00:00 GMT-0400 (Eastern Daylight Time) {}
shift_num: 1
vTurnReport_Attachments: []
答案1
得分: 0
不是正确答案
字符串末尾的'Z'表示时间为UTC。
仅仅将其从'T00:00:00.000Z'
中移除将使JS将其解析为本地时区。
new Date("2023-04-01T00:00Z");
// 星期六,2023年4月1日,02:00:00 GMT+0200
new Date("2023-04-01T00:00");
// 星期六,2023年4月1日,00:00:00 GMT+0200
英文:
Not the correct answer
The 'Z' at the end of your DateTime string signifies that the time is in UTC.
<strike>Simply removing it from 'T00:00:00.000Z'
will make JS parse it in it's local time zone.</strike>
new Date("2023-04-01T00:00Z");
// Sat Apr 01 2023 02:00:00 GMT+0200
new Date("2023-04-01T00:00");
// Sat Apr 01 2023 00:00:00 GMT+0200
答案2
得分: 0
我找到了一个解决方案,我能够使用。我创建了将从我的prisma客户端接收到的日期/时间转换并添加到名为prismaFunction.js的文件中的函数。然后,无论我在哪里使用来自prisma的日期或将日期发送到prisma,我都会导入这些函数。我使用了date-fns来制作这些函数。这些函数考虑了夏令时。
//用于修复prisma日期时间的函数,如果数据库时间不是以UTC保存的
import { format } from 'date-fns';
//将修复的日期时间发送到数据库,如果数据库时间不是UTC
export function fixedDateToPrisma(date) {
return format(date, "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
};
//修复prisma的时区问题,如果数据库时间不是utc
export function fixedDateFromPrisma(date) {
return new Date(date.substring(0, date.length - 1));
};
这是我将日期发送到prisma的示例。在这里,我从url请求获取我的日期,然后将修复的日期发送到服务器。
import { fixedDateToPrisma } from '../../../prismaFunctions';
/** @type {import('./$types').RequestHandler} */
export async function PUT({ request }) {
try {
const { alertId, modalComment, modalDeptId } = await request.json();
await prisma.TurnReport_Alerts.update({
where: {
alert_id: alertId
},
data: {
alert_comment: modalComment,
dt_updated: fixedDateToPrisma(new Date()),
}
})
await prisma.$disconnect()
return json()
} catch (error) {
console.log(error)
return new Response(JSON.stringify({ message: error.message }), { status: 500 });
}
}
这是在组件内使用它的示例,在这里我获取日期并进行转换。在我的情况下,我从props中获取它,但如果你从fetch调用中获取它,它也会起作用。希望这对其他遇到相同问题的人有帮助!
<script>
export let data;
import {fixedDateFromPrisma} from '../prismaFunctions';
</script>
<h1>Date: {fixedDateFromPrisma(data.date)}</h1>
英文:
I have found a solution that I am able to use. I made functions that will convert the date/times recieved from my prisma client and added them to a file called prismaFunction.js. And then anywhere I use dates from prisma or send dates to prisma I import the functions. I used date-fns for these functions. These functions account for daylight savings time.
//functions used to fix prisma datetime if database times are not being saved in UTC
import { format } from 'date-fns';
//fixed datetimes sent to database if database times are not in UTC
export function fixedDateToPrisma(date) {
return format(date, "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
};
//fix timezone issue from prisma if database times are not in utc
export function fixedDateFromPrisma(date) {
return new Date(date.substring(0, date.length - 1));
};
Here is an example of how I would send a date to prisma. Here I am getting my date from the url request and then sending the fixed date to the server.
import { fixedDateToPrisma } from '../../../prismaFunctions';
/** @type {import('./$types').RequestHandler} */
export async function PUT({ request }) {
try {
const { alertId, modalComment, modalDeptId } = await request.json();
await prisma.TurnReport_Alerts.update({
where: {
alert_id: alertId
},
data: {
alert_comment: modalComment,
dt_updated: fixedDateToPrisma(new Date()),
}
})
await prisma.$disconnect()
return json()
} catch (error) {
console.log(error)
return new Response(JSON.stringify({ message: error.message }), { status: 500 });
}
}
And here is an example of using it inside a component where I am getting the date and converting it. In my case I am getting it from props but it will work the same if you are getting if from your fetch call. I hope this helps anyone else having the same problem!
<script>
export let data;
import {fixedDateFromPrisma} from '../prismaFunctions'
</script>
<h1>Date: {fixedDateFromPrisma(data.date)}</h1>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论