波斯日历 - 从Oracle DB以波斯语格式插入和检索日期



我的应用程序需要以下内容。

在我的应用程序(在支撑杆中(中,我们需要支持波斯日历。

当我们提交表格时,日期将作为字符串在动作类中。我们需要将该日期保存在DB中。我们为波斯日历配置了DB。而且,从DB用户检索数据时,应仅以波斯语格式查看日期。

另外,用户可以用两种语言切换(英语,波斯语(。因此,应用程序应支持这两种类型的日历(Gregorian和Persian(。如果用户登录英语,则应可见Gregorian日历。如果用户登录波斯语,则应可见波斯日历。

对于从格里高利(Gregorian(到波斯语的日期转换,我正在使用以下:http://www.dailyfreecode.com/forum/converter-gregorian-date-jalali-date-date-20288.aspx

在上述要求中,我面临2个问题:

  1. 在提交表单时,我们如何以DB格式保存日期(在行动类中以字符串格式为字符串格式(?
  2. 在从数据库中检索数据时,应以波斯语格式出现。截至目前,JDBC客户端正在检索Gregorian Calender的日期。

我正在通过java.sql.date(今天的日期(,它以DB中的波斯格式保存。使用以下代码。

java.sql.Date sqlDate = null; 
java.util.Date utilDate = new Date(); 
sqlDate = new java.sql.Date(utilDate.getTime()); 
PreparedStatement psmtInsert = conn.prepareStatement(insertQuery); 
psmtInsert.setDate(1, sqlDate)); 
psmtInsert.executeUpdate();

检索:

PreparedStatement psmtSelect = conn.prepareStatement("select dateOfJoining from EMPLOYEE");
ResultSet resultSet = psmtSelect.executeQuery();
while (resultSet.next()) {
    System.out.println(resultSet.getDate(1));
}

,但它是格里高利类型的返回日期。

我们是否在tomcat/jvm/jdbc client中有任何设置,它将从db返回的日期转换为波斯格式本身(就像我们有nls_calendar,nls_date_format in Oracle中的nls_calendar(?

对于第一期,如果我以波斯语格式传递日期,则在db中会保存错误。PFB我的代码:

java.sql.Date sqlDate = null; 
java.util.Date utilDate = new Date("1397/02/04"); 
sqlDate = new java.sql.Date(utilDate.getTime()); 
PreparedStatement psmtInsert = conn.prepareStatement(insertQuery); 
psmtInsert.setDate(1, sqlDate)); 
psmtInsert.executeUpdate();

上面的插入为0777/09/13 in db。

我们如何克服上述问题?预先感谢。

java.sql.Date中没有日历类型,因此不可能将其强加于 persian 。JDBC中的所有日期/时间值以中性形式进行了归一化,Oracle数据库也使用中性形式以及存储和处理。当NLS_CALENDAR是波斯语时,Oracle会转换为中性形式的值,这是"呈现"它在内部中性形式处理时在波斯日历大会中。

通常,将中性形式始终用于后端中的所有值是最佳的。通常,在UI层中使用转换器作为本地化的一部分,以量身定制为单个用户的首选语言环境。如果需要在中间层中的Java进行定位,则道格拉斯建议的java.time.chrono软件包将是一个干净的解决方案。

在提交表单时,如何以DB格式保存日期(在行动类中以字符串格式为字符串格式(?

将日期存储为DATE数据类型,当您将其插入表中时,将其与nls Calendar参数一起使用Persion格式的字符串将其转换为日期:

: :

sql小提琴

查询1

SELECT TO_DATE(
         '1397/02/05',
         'yyyy/mm/dd',
         'nls_calendar=persian'
       )
FROM   DUAL

结果

| TO_DATE('1397/02/05','YYYY/MM/DD','NLS_CALENDAR=PERSIAN') |
|-----------------------------------------------------------|
|                                      2018-04-25T00:00:00Z |

从DB中检索数据时,应以波斯语格式出现。截至目前,JDBC客户端正在检索Gregorian Calender的日期。

输出值时,只需指定要使用的日历以格式化它即可。因此,对于波斯语,将TO_CHAR与NLS日历参数用于波斯语:

查询2

SELECT TO_CHAR(
         DATE '2018-04-25',
         'yyyy/mm/dd',
         'nls_calendar=persian'
       )
FROM   DUAL

结果

| TO_CHAR(DATE'2018-04-25','YYYY/MM/DD','NLS_CALENDAR=PERSIAN') |
|---------------------------------------------------------------|
|                                                    1397/02/05 |

我们有任何方法使用JDBC客户端以波斯语格式检索日期。

这是一个常见的误解。DATE数据类型存储在Oracle表中为7个字节,其中包含年度(2个字节(,月,天,小时,分钟,分钟和秒(每个字节1个(。它没有任何"格式"(但有效地存储在Gregorian日历中(。

JDBC不传输格式的日期,它只是将这些7个字节传输并将其存储在java.sql.Date类中(也只是存储这些字节(。

如果要格式化DATE数据类型,则需要将其转换为另一种数据类型;通常是要在Oracle数据库中使用TO_CHAR的字符串(或在Java中格式化日期的其他方法(。

只是为那些仍在寻找如何在应用程序中实现波斯日历的人提供输入。

我的应用程序应支持Gregorian和Persian日历,也应支持Oracle和Postgresql DB。

以最低限度的努力执行以下步骤:

  1. 使用以下链接中建议的实现将从UI从UI转换为validate((的Gregorian格式http://www.dailyfreecode.com/forum/converter-gregorian-date-jalali-date-date-20288.aspx

  2. 一旦将日期转换为Gregorian,整个应用程序将继续运行,因为它在Gregorian Date的早期运行时将继续运行。

  3. 在将日期保存到DB中时,我决定仅以Gregorian格式存储日期,因为我还需要支持PostgreSQL DB,并且不支持波斯日历。

  4. 在将数据获取到UI时,将从DB中检索日期,并且我再次以波斯的格式转换日期。

要在UI上显示波斯日历,请参阅下面的链接。它还有其他日历实现http://keith-wood.name/calendars.html

上述方法可以帮助实现大多数不同的日历。

java.sql.Date定义为在Gregorian的UTC中。从数据库中获得java.sql.Date的日期不太可能做任何有用的事情。正确的答案是定义PersianChronology,该CC_13扩展了java.time.chrono.AbstractChronologyPersianLocalDatejava.time.chrono.ChronoLocalDate。然后从数据库中获取PersianLocalDate的值。这是很多工作,但从理论上讲,这是正确的事情。

PersianLocalDate per = rs.getObject(col, PersianLocalDate.class);

我认为这可以使其工作。不容易,但可能。如果您的PersianLocalDate类定义以下方法

public static PersianLocalDate of(oracle.sql.DATE date) { ... }

然后,Oracle数据库JDBC将使用该方法在上面的getObject调用中构造PersianLocalDate。有趣的部分将是实现of(DATE)方法。所有oracle.sql.DATE方法都假设一个Gregorian日历。最好的选择是致电DATE.getBytes并自己解释字节。字节0和1是一年,第2个是一个月,3个是本月的一天。TIMESTAMP.getJavaYear将将这两个字节转换为INT年。它对日历一无所知;只是在做算术。取决于数据库在发送波斯日期作为查询结果时所做的事情,该结果应该让您构建PersianLocalDate。如果数据库转换为Gregorian,则必须转换回波斯语。您的PersianChronology应该有所帮助。

以另一种方式走,将PersianLocalDate发送到数据库将变得更加有趣。Oracle数据库JDBC驱动程序没有能力将未知类转换为诸如日期之类的数据库类型,没有等于上述of方法。您可以尝试使PersianLocalDate扩展oracle.sql.ORADatatoDatum方法必须以与数据库作为查询结果相同的字节返回oracle.sql.DATE

也许一种简单的方法是将波斯的日期来回发送到数据库作为Varchars/字符串。驱动程序将在PersianLocalDate上调用static of(String)方法,因此获得PersianLocalDate很容易。如果数据库对PersianLocalDate.toString结果做正确的事情,则调用setString使发送值的发送使其变得容易。如果不是,则定义PersianLocalDate.toDatabaseString并自己进行转换。

这是我们在实施java.time支持时谈论的用例,但我们根本没有任何做任何事情所需的资源。而且我们不知道这将有多普遍,所以很难证明做这项工作是合理的。如果您有支持合同,我鼓励您提交SR并要求提高请求。如果您可以提供PersianChronologyPersianLocalDate,那么我更容易获得分配的资源来做某事。也许只不过是一个使setObject起作用的钩子,但至少这就是钩子。我希望我能提供更多的帮助。

相关内容

  • 没有找到相关文章

最新更新