You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Struts应用中Oracle数据库波斯历与公历的适配需求

我来一步步帮你搞定Struts应用适配波斯历(贾拉利历)的需求,同时支持英/波双语切换和双日历系统适配:

核心思路

整体流程是:前端提交波斯历格式的日期字符串 → Action层解析为对应日期对象 → 存入已配置波斯历的Oracle数据库 → 检索时根据当前语言/日历设置,将日期格式化为波斯历或公历展示。

1. 表单提交与Action层处理

首先,前端表单提交的是波斯历格式的字符串(比如 1403/05/15),Action类接收该参数后,需要用波斯历专用的日期库解析成日期对象。推荐使用ThreeTen-Extra库(和Java 8+的java.time API兼容)来处理贾拉利历,也可以用ICU4J库。

示例代码如下:

import org.threeten.extra.chrono.JalaliChronology;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Locale;

public class DateAction extends ActionSupport {
    // 接收表单提交的波斯历日期字符串
    private String persianDateStr;

    public String submitDate() {
        // 配置波斯历格式化器
        DateTimeFormatter jalaliFormatter = DateTimeFormatter.ofPattern("yyyy/MM/dd")
                .withChronology(JalaliChronology.INSTANCE)
                .withLocale(new Locale("fa"));
        
        // 解析字符串为贾拉利历LocalDate对象
        LocalDate jalaliDate = LocalDate.parse(persianDateStr, jalaliFormatter);
        
        // 调用DAO层将日期存入Oracle数据库(后续步骤会讲DAO适配)
        dateDao.saveJalaliDate(jalaliDate);
        
        return SUCCESS;
    }

    // getter/setter
    public String getPersianDateStr() { return persianDateStr; }
    public void setPersianDateStr(String persianDateStr) { this.persianDateStr = persianDateStr; }
}
2. Oracle数据库存储适配

既然你的Oracle已经配置了波斯历(通常是设置NLS_CALENDAR='PERSIAN'),数据库的DATE类型会自动以波斯历存储日期。

如果用Hibernate等ORM框架,需要自定义类型映射来适配贾拉利历:

// 自定义Hibernate类型:映射贾拉利历LocalDate到数据库DATE类型
public class JalaliLocalDateType extends AbstractSingleColumnStandardBasicType<LocalDate> {
    public JalaliLocalDateType() {
        super(VarcharTypeDescriptor.INSTANCE, new JalaliLocalDateJavaTypeDescriptor());
    }

    @Override
    public String getName() {
        return "jalali_local_date";
    }
}

然后在实体类中使用该类型:

@Type(type = "com.yourpackage.JalaliLocalDateType")
@Column(name = "PERSIAN_DATE_COLUMN")
private LocalDate persianDate;

如果用原生JDBC,直接将解析后的LocalDate(贾拉利历)通过PreparedStatement存入即可,Oracle会自动适配波斯历存储。

3. 检索时的日期格式化展示

从数据库取出日期后,需要根据当前用户的语言设置,决定展示波斯历还是公历:

  1. 首先配置Struts国际化资源文件:

    • messages_fa.properties(波斯文):date.format=yyyy/MM/dd
    • messages_en.properties(英文):date.format=MM/dd/yyyy
  2. 在Action中根据当前Locale格式化日期:

public String retrieveDate() {
    // 从数据库取出存储的日期
    LocalDate storedDate = dateDao.getDateById(1);
    Locale currentLocale = ActionContext.getContext().getLocale();
    DateTimeFormatter formatter;

    if (currentLocale.getLanguage().equals("fa")) {
        // 波斯语环境:用贾拉利历格式化
        formatter = DateTimeFormatter.ofPattern(getText("date.format"))
                .withChronology(JalaliChronology.INSTANCE)
                .withLocale(currentLocale);
    } else {
        // 英语环境:用公历格式化
        formatter = DateTimeFormatter.ofPattern(getText("date.format"))
                .withLocale(currentLocale);
    }

    // 格式化后存入request,供JSP展示
    request.setAttribute("displayDate", storedDate.format(formatter));
    return SUCCESS;
}
  1. 在JSP中展示日期:
<p><s:text name="display.date.label"/> : <s:property value="displayDate"/></p>
4. 双语与日历系统切换

Struts的国际化切换可以通过设置Locale实现,同时自动适配对应日历系统:

  1. 编写切换语言的Action:
public String switchLanguage() {
    String lang = request.getParameter("lang");
    Locale newLocale = new Locale(lang);
    // 设置当前请求的Locale
    ActionContext.getContext().setLocale(newLocale);
    // 将Locale存入Session,保持会话级别的语言设置
    session.put("WW_TRANS_I18N_LOCALE", newLocale);
    return SUCCESS;
}
  1. 前端添加切换按钮:
<a href="<s:url action='switchLanguage'><s:param name='lang' value='en'/></s:url>">English</a>
<a href="<s:url action='switchLanguage'><s:param name='lang' value='fa'/></s:url>">فارسی</a>

切换到波斯语时,自动用波斯历解析和展示日期;切换到英语时,用公历处理。

关键注意事项
  • 确保项目引入了ThreeTen-Extra或ICU4J库,用于处理贾拉利历的日期解析和格式化。
  • 检查Oracle的NLS配置:NLS_CALENDAR='PERSIAN'、NLS_DATE_FORMAT='YYYY/MM/DD'(匹配波斯历格式)。
  • 前端建议使用波斯历日期选择器(比如jQuery Jalali Datepicker),避免用户输入错误格式的日期字符串。

内容的提问来源于stack exchange,提问作者Tejeshvi Roy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 08:28:53