From 79203296e9380f7c07cc132871a5729c8e190e5e Mon Sep 17 00:00:00 2001
From: Evgenij Ryazanov <katzyn@gmail.com>
Date: Wed, 14 Feb 2018 19:41:54 +0800
Subject: [PATCH] Write week years in TO_CHAR correctly

---
 h2/src/main/org/h2/util/ToChar.java           | 20 +++++++++++++++----
 h2/src/test/org/h2/test/db/TestFunctions.java |  9 +++++++++
 2 files changed, 25 insertions(+), 4 deletions(-)

diff --git a/h2/src/main/org/h2/util/ToChar.java b/h2/src/main/org/h2/util/ToChar.java
index a03cd8f4f..d903e58c1 100644
--- a/h2/src/main/org/h2/util/ToChar.java
+++ b/h2/src/main/org/h2/util/ToChar.java
@@ -785,18 +785,30 @@ public class ToChar {
                 }
                 StringUtils.appendZeroPadded(output, 4, posYear);
                 i += 5;
-            } else if ((cap = containsAt(format, i, "YYYY", "IYYY", "RRRR")) != null) {
+            } else if ((cap = containsAt(format, i, "YYYY", "RRRR")) != null) {
                 StringUtils.appendZeroPadded(output, 4, posYear);
                 i += 4;
-            } else if ((cap = containsAt(format, i, "YYY", "IYY")) != null) {
+            } else if ((cap = containsAt(format, i, "IYYY")) != null) {
+                StringUtils.appendZeroPadded(output, 4, DateTimeUtils.getIsoWeekYear(dateValue));
+                i += 4;
+            } else if ((cap = containsAt(format, i, "YYY")) != null) {
                 StringUtils.appendZeroPadded(output, 3, posYear % 1000);
                 i += 3;
-            } else if ((cap = containsAt(format, i, "YY", "IY", "RR")) != null) {
+            } else if ((cap = containsAt(format, i, "IYY")) != null) {
+                StringUtils.appendZeroPadded(output, 3, DateTimeUtils.getIsoWeekYear(dateValue) % 1000);
+                i += 3;
+            } else if ((cap = containsAt(format, i, "YY", "RR")) != null) {
                 StringUtils.appendZeroPadded(output, 2, posYear % 100);
                 i += 2;
-            } else if ((cap = containsAt(format, i, "I", "Y")) != null) {
+            } else if ((cap = containsAt(format, i, "IY")) != null) {
+                StringUtils.appendZeroPadded(output, 2, DateTimeUtils.getIsoWeekYear(dateValue) % 100);
+                i += 2;
+            } else if ((cap = containsAt(format, i, "Y")) != null) {
                 output.append(posYear % 10);
                 i += 1;
+            } else if ((cap = containsAt(format, i, "I")) != null) {
+                output.append(DateTimeUtils.getIsoWeekYear(dateValue) % 10);
+                i += 1;
 
                 // Month / quarter
 
diff --git a/h2/src/test/org/h2/test/db/TestFunctions.java b/h2/src/test/org/h2/test/db/TestFunctions.java
index d5bd323bf..1ce38a2ae 100644
--- a/h2/src/test/org/h2/test/db/TestFunctions.java
+++ b/h2/src/test/org/h2/test/db/TestFunctions.java
@@ -1486,6 +1486,15 @@ public class TestFunctions extends TestBase implements AggregateFunction {
         assertResult("0 BC", stat,
                 "SELECT TO_CHAR(X, 'Y BC') FROM U");
         assertResult("1979 A.D.", stat, "SELECT TO_CHAR(X, 'YYYY B.C.') FROM T");
+        assertResult("2013", stat, "SELECT TO_CHAR(DATE '2013-12-30', 'YYYY') FROM DUAL");
+        assertResult("013", stat, "SELECT TO_CHAR(DATE '2013-12-30', 'YYY') FROM DUAL");
+        assertResult("13", stat, "SELECT TO_CHAR(DATE '2013-12-30', 'YY') FROM DUAL");
+        assertResult("3", stat, "SELECT TO_CHAR(DATE '2013-12-30', 'Y') FROM DUAL");
+        // ISO week year
+        assertResult("2014", stat, "SELECT TO_CHAR(DATE '2013-12-30', 'IYYY') FROM DUAL");
+        assertResult("014", stat, "SELECT TO_CHAR(DATE '2013-12-30', 'IYY') FROM DUAL");
+        assertResult("14", stat, "SELECT TO_CHAR(DATE '2013-12-30', 'IY') FROM DUAL");
+        assertResult("4", stat, "SELECT TO_CHAR(DATE '2013-12-30', 'I') FROM DUAL");
         assertResult("08:12 AM", stat, "SELECT TO_CHAR(X, 'HH:MI AM') FROM T");
         assertResult("08:12 A.M.", stat, "SELECT TO_CHAR(X, 'HH:MI A.M.') FROM T");
         assertResult("02:04 P.M.", stat, "SELECT TO_CHAR(X, 'HH:MI A.M.') FROM U");
-- 
2.18.1