Java - 以日期格式交换月和日

问题描述 投票:0回答:1

我有一个String日期格式(例如dd / MM / yyyy),并希望以编程方式将其转换为具有月份的美式风格(例如MM / dd / yyyy)。

这种情况的用例是读取一些数据并确定哪种格式最合适。

这听起来很简单,但实际上尝试实现它,我的解决方案似乎是次优的。

以下是我的尝试,包括测试。

public class DateSwapperExample
{
    private static final char dateFormatDayLetter = 'd', dateFormatMonthLetter = 'M';

    /**
     * Swaps the Day & Month component in a Date Format, if both are present <br>
     * When swapping, ensures the frequency is retained - e.g. dd/MMM -> MMM/dd <br>
     * TODO Only handles one instance of each tag <br>
     * TODO This doesn't handle quoted elements in the Date Format (e.g. "dd/mm 'since dave made the best cakes' yyyy")
     */
    private static String swapDayAndMonthInDateFormat(final String dateFormat)
    {
        // Get the position of the groups
        final int[] dayIndex = new int[] {dateFormat.indexOf(dateFormatDayLetter), dateFormat.lastIndexOf(dateFormatDayLetter)};
        final int[] monthIndex = new int[] {dateFormat.indexOf(dateFormatMonthLetter), dateFormat.lastIndexOf(dateFormatMonthLetter)};

        if ((dayIndex[0] == -1) || (monthIndex[0] == -1))
        {
            // Cannot swap as dateFormat does not contain both dateFormatDayLetter & dateFormatMonthLetter
            return dateFormat;
        }
        else
        {
            final int[] firstGroup, secondGroup;

            // Work out which group comes first
            if (dayIndex[0] < monthIndex[0])
            {
                firstGroup = dayIndex;
                secondGroup = monthIndex;
            }
            else
            {

                firstGroup = monthIndex;
                secondGroup = dayIndex;
            }

            // Split the string up into segments, re-organise and combine

            // The other parts of the format at the start
            return substringConstrained(dateFormat, 0, firstGroup[0])
                    // The second group
                    + substringConstrained(dateFormat, secondGroup[0], secondGroup[1] + 1)
                    // The other parts of the format in the middle
                    + substringConstrained(dateFormat, firstGroup[1] + 1, secondGroup[0])
                    // The first group
                    + substringConstrained(dateFormat, firstGroup[0], firstGroup[1] + 1)
                    // The other parts of the format at the end
                    + substringConstrained(dateFormat, secondGroup[1] + 1, dateFormat.length());
        }
    }

    /** Extension of {@link String#substring(int, int)} that constrains the index parameters to be within the allowed range */
    private static String substringConstrained(final String str, final int beginIndex, final int endIndex)
    {
        return str.substring(constrainToRange(beginIndex, 0, str.length()), constrainToRange(endIndex, 0, str.length()));
    }

    /** Copy of {@link com.google.common.primitives.Ints#constrainToRange(int, int, int)} to avoid the need of Guava in this example */
    private static int constrainToRange(int value, int min, int max)
    {
        return Math.min(Math.max(value, min), max);
    }

    @org.junit.Test
    public void testSwapDayAndMonthInDateFormat()
    {
        org.junit.Assert.assertEquals("Md", swapDayAndMonthInDateFormat("dM"));
        org.junit.Assert.assertEquals("MMd", swapDayAndMonthInDateFormat("dMM"));
        org.junit.Assert.assertEquals("Mdy", swapDayAndMonthInDateFormat("dMy"));
        org.junit.Assert.assertEquals("Myd", swapDayAndMonthInDateFormat("dyM"));
        org.junit.Assert.assertEquals("yMd", swapDayAndMonthInDateFormat("ydM"));
        org.junit.Assert.assertEquals("aMbdc", swapDayAndMonthInDateFormat("adbMc"));
        org.junit.Assert.assertEquals("MM/dd/yyyy", swapDayAndMonthInDateFormat("dd/MM/yyyy"));
        org.junit.Assert.assertEquals("MMM/dd/yyyy", swapDayAndMonthInDateFormat("dd/MMM/yyyy"));

        for (final String str : new String[] {"ydy", "yMy", "yDy", "ymy", "Dm", "Dmm", "DD/mm/yyyy", "DD/mmm/yyyy"})
        {
            org.junit.Assert.assertEquals(str, swapDayAndMonthInDateFormat(str));
        }
    }
}
java simpledateformat date-format
1个回答
3
投票
private static String swapDayAndMonthInDateFormat(final String dateFormat)
{
    return dateFormat.replaceFirst("(d+)(.*?)(M+)", "$3$2$1");
}

我不相信这是解决你真正问题的好方法。但它会让你测试通过。

你也不应该使用SimpleDateFormat。这堂课非常麻烦,而且Date和朋友们已经过时了。而是使用DateTimeFormatter和java.time中的其他类,现代Java日期和时间API。但格式模式字符串看起来仍然相似,所以可能这个答案仍然相关。

© www.soinside.com 2019 - 2024. All rights reserved.