修改时间时区问题

This commit is contained in:
dxc
2026-02-05 14:36:36 +08:00
parent 0bc47d306d
commit 4f90e02dcf
4 changed files with 40 additions and 16 deletions

View File

@ -3,7 +3,7 @@ from app.extensions import db
from app.models.inbound.buy import StockBuy from app.models.inbound.buy import StockBuy
from app.models.base import MaterialBase from app.models.base import MaterialBase
from app.models.outbound import TransOutbound from app.models.outbound import TransOutbound
from datetime import datetime from datetime import datetime, timedelta, timezone # [修改] 引入 timezone
from sqlalchemy import or_, func, text, and_ from sqlalchemy import or_, func, text, and_
import traceback import traceback
import json import json
@ -40,7 +40,7 @@ class BuyInboundService:
return [] return []
# ============================================================ # ============================================================
# 2. 新增入库逻辑 (修改:精确到时间) # 2. 新增入库逻辑 (强制北京时间)
# ============================================================ # ============================================================
@staticmethod @staticmethod
def handle_inbound(data): def handle_inbound(data):
@ -51,8 +51,11 @@ class BuyInboundService:
material = MaterialBase.query.get(base_id) material = MaterialBase.query.get(base_id)
if not material: raise ValueError("物料不存在") if not material: raise ValueError("物料不存在")
# [核心修改] 默认使用当前时间(含时分秒),不再截取 .date() # [核心修改] 获取当前北京时间 (UTC+8)
current_time = datetime.now() # 无论服务器在 UTC 还是其他时区,这里强制转换为 UTC+8 并去掉时区信息存入数据库
beijing_tz = timezone(timedelta(hours=8))
current_time = datetime.now(beijing_tz).replace(tzinfo=None)
in_date_val = current_time in_date_val = current_time
if data.get('in_date'): if data.get('in_date'):
@ -62,12 +65,12 @@ class BuyInboundService:
if len(date_str) > 10: if len(date_str) > 10:
in_date_val = datetime.strptime(date_str, '%Y-%m-%d %H:%M:%S') in_date_val = datetime.strptime(date_str, '%Y-%m-%d %H:%M:%S')
else: else:
# 如果只传了日期,手动补上当前时间的时分秒,保证同日入库的排序正确 # 如果只传了日期,使用该日期 + 当前北京时间的时分秒
d_temp = datetime.strptime(date_str, '%Y-%m-%d') d_temp = datetime.strptime(date_str, '%Y-%m-%d')
in_date_val = datetime(d_temp.year, d_temp.month, d_temp.day, in_date_val = datetime(d_temp.year, d_temp.month, d_temp.day,
current_time.hour, current_time.minute, current_time.second) current_time.hour, current_time.minute, current_time.second)
except: except:
# 解析失败则使用当前时间作为兜底 # 解析失败则使用当前北京时间
in_date_val = current_time in_date_val = current_time
in_qty = float(data.get('in_quantity') or 0) in_qty = float(data.get('in_quantity') or 0)

View File

@ -2,7 +2,7 @@
from app.extensions import db from app.extensions import db
from app.models.base import MaterialBase from app.models.base import MaterialBase
from app.models.outbound import TransOutbound from app.models.outbound import TransOutbound
from datetime import datetime from datetime import datetime, timedelta, timezone # [修改]
from sqlalchemy import or_, func, text, and_ from sqlalchemy import or_, func, text, and_
import traceback import traceback
import json import json
@ -33,7 +33,7 @@ class ProductInboundService:
return [] return []
# ============================================================ # ============================================================
# 2. 新增入库逻辑 (修改:精确到时间) # 2. 新增入库逻辑 (强制北京时间)
# ============================================================ # ============================================================
@staticmethod @staticmethod
def handle_inbound(data): def handle_inbound(data):
@ -45,8 +45,10 @@ class ProductInboundService:
material = MaterialBase.query.get(base_id) material = MaterialBase.query.get(base_id)
if not material: raise ValueError("物料不存在") if not material: raise ValueError("物料不存在")
# [核心修改] 处理 production_date包含时分秒 # [核心修改] 强制北京时间
current_time = datetime.now() beijing_tz = timezone(timedelta(hours=8))
current_time = datetime.now(beijing_tz).replace(tzinfo=None)
in_date_val = current_time in_date_val = current_time
if data.get('in_date'): if data.get('in_date'):

View File

@ -2,7 +2,7 @@
from app.extensions import db from app.extensions import db
from app.models.base import MaterialBase from app.models.base import MaterialBase
from app.models.outbound import TransOutbound from app.models.outbound import TransOutbound
from datetime import datetime from datetime import datetime, timedelta, timezone # [修改]
from sqlalchemy import or_, func, text, and_ from sqlalchemy import or_, func, text, and_
import traceback import traceback
import json import json
@ -52,8 +52,10 @@ class SemiInboundService:
if not material: if not material:
raise ValueError(f"ID为 {base_id} 的基础物料不存在") raise ValueError(f"ID为 {base_id} 的基础物料不存在")
# [核心修改] 处理入库日期(production_date),包含时分秒 # [核心修改] 强制北京时间
current_time = datetime.now() beijing_tz = timezone(timedelta(hours=8))
current_time = datetime.now(beijing_tz).replace(tzinfo=None)
in_date_val = current_time in_date_val = current_time
if data.get('in_date'): if data.get('in_date'):

View File

@ -1,5 +1,5 @@
import uuid import uuid
from datetime import datetime from datetime import datetime, timezone, timedelta # [修改] 引入 timezone 和 timedelta
from sqlalchemy import or_ from sqlalchemy import or_
from app.extensions import db from app.extensions import db
from app.models.outbound import TransOutbound from app.models.outbound import TransOutbound
@ -16,8 +16,15 @@ class OutboundService:
@staticmethod @staticmethod
def generate_outbound_no(): def generate_outbound_no():
"""生成出库单号: OUT-yyyyMMdd-随机码""" """
date_str = datetime.now().strftime('%Y%m%d') 生成出库单号: OUT-yyyyMMdd-随机码
[修改] 强制使用北京时间生成日期前缀
"""
# 获取北京时间
beijing_tz = timezone(timedelta(hours=8))
current_time = datetime.now(beijing_tz)
date_str = current_time.strftime('%Y%m%d')
short_uuid = uuid.uuid4().hex[:6].upper() short_uuid = uuid.uuid4().hex[:6].upper()
return f"OUT-{date_str}-{short_uuid}" return f"OUT-{date_str}-{short_uuid}"
@ -143,6 +150,12 @@ class OutboundService:
stock_item.stock_quantity = float(stock_item.stock_quantity) - quantity stock_item.stock_quantity = float(stock_item.stock_quantity) - quantity
stock_item.available_quantity = float(stock_item.available_quantity) - quantity stock_item.available_quantity = float(stock_item.available_quantity) - quantity
# [新增] 计算北京时间
beijing_tz = timezone(timedelta(hours=8))
# replace(tzinfo=None) 是为了让存入数据库的时间变为 naive time (不带时区信息的本地时间)
# 这样数据库看起来就是 "2023-10-27 15:00:00" 而不是 UTC 时间
current_time = datetime.now(beijing_tz).replace(tzinfo=None)
# 5. 创建出库记录 # 5. 创建出库记录
new_outbound = TransOutbound( new_outbound = TransOutbound(
outbound_no=OutboundService.generate_outbound_no(), outbound_no=OutboundService.generate_outbound_no(),
@ -154,6 +167,10 @@ class OutboundService:
quantity=quantity, quantity=quantity,
consumer_name=data.get('consumer_name'), consumer_name=data.get('consumer_name'),
signature_path=data.get('signature_path'), # 存储签名的 URL signature_path=data.get('signature_path'), # 存储签名的 URL
# [关键] 显式设置北京时间,覆盖 Model 中的 default=datetime.now (UTC)
outbound_time=current_time,
operator_name=operator_name, operator_name=operator_name,
remark=data.get('remark') remark=data.get('remark')
) )