JAVA按列对CSV文件进行排序,然后按日期对列进行正确排序

时间:2019-03-19 02:29:23

标签: java csv sorting

我正试图弄清为什么我的日期排序不起作用。

我想按一些选择列(字符串)然后按日期列对CSV文件进行排序。 但是,它不能正确地对日期进行排序-它似乎只是按日期的第一部分( 25 / 12/2018)而不是确切的日期排序。

public class MultiColumnCsvSort
{
private static final String COLUMN_SEPARATOR = ",";

public static void main(String[] args) throws Exception
{
    InputStream inputStream = new FileInputStream("order_lines_file.csv");
    List<List<String>> lines = readCsv(inputStream);

    // Create a comparator that sorts primarily by column 0,
    // and if these values are equal, by column 2
    Comparator<List<String>> comparator = createComparator(2,1,5);
    Collections.sort(lines, comparator);


    OutputStream outputStream = new FileOutputStream("output.csv");
    String header = "order id, sku, store, location, quantity, date";
    writeCsv(header, lines, outputStream);        
}
private static List<List<String>> readCsv(
    InputStream inputStream) throws IOException
{
    BufferedReader reader = new BufferedReader(
        new InputStreamReader(inputStream));
    List<List<String>> lines = new ArrayList<List<String>>();

    // Skip header
    String line = reader.readLine();

    while (true)
    {
        line = reader.readLine();
        if (line == null)
        {
            break;
        }
        List<String> list = Arrays.asList(line.split(COLUMN_SEPARATOR));
        lines.add(list);
    }
    return lines;
}
private static void writeCsv(
    String header, List<List<String>> lines, OutputStream outputStream) 
    throws IOException
{
    Writer writer = new OutputStreamWriter(outputStream);
    writer.write(header+"\n");
    for (List<String> list : lines)
    {
        for (int i = 0; i < list.size(); i++)
        {
            writer.write(list.get(i));
            if (i < list.size() - 1)
            {
                writer.write(COLUMN_SEPARATOR);
            }
        }
        writer.write("\n");
    }
    writer.close();
}

private static <T extends Comparable<? super T>> Comparator<List<T>> 
    createComparator(int... indices)
{
    return createComparator(MultiColumnCsvSort.<T>naturalOrder(), indices);
}

private static <T extends Comparable<? super T>> Comparator<T>
    naturalOrder()
{
    return new Comparator<T>()
    {
        @Override
        public int compare(T t0, T t1)
        {
            return t0.compareTo(t1);
        }
    };
}
private static <T> Comparator<List<T>> createComparator(
    final Comparator<? super T> delegate, final int... indices)
{
    return new Comparator<List<T>>()
    {
        @Override
        public int compare(List<T> list0, List<T> list1)
        {   
            for (int i = 0; i < indices.length; i++)
            {
                T element0 = list0.get(indices[i]);
                T element1 = list1.get(indices[i]);
                        int n = delegate.compare(element0, element1);
                        if (n != 0)
                        {
                            return n;
                        }
            }
            return 0;
        }
    };
}

}

我从这篇文章中摘录了

How to sort csv file by two columns in java?

但是,当我知道在这些值之间有日期的行时,输出如下所示: current sorted file

1 个答案:

答案 0 :(得分:0)

YYYY-MM-DD(ISO 8601格式)

  

在日期的第一部分(2018年12月25日)而不是确切的日期排序。

因此将字符串变形为标准ISO 8601格式(YYYY-MM-DD)。按字母顺序排序的值也将按时间顺序排列。

解析输入字符串

定义一种格式设置以匹配您的输入。

String input = "25/12/2018" ;
DateTimeFormatter f = DateTimeFormatter.ofPattern( "dd/MM/uuuu" ) ;
LocalDate ld = LocalDate.parse( input , f ) ;

当然,您应该在实际代码中缓存DateTimeFormatter对象。请注意, java.time 类是thread-safe,并使用不可变对象模式。

生成输出字符串

java.time 类在生成/解析字符串时默认使用标准ISO 8601格式。因此,无需指定格式设置模式。

String output = ld.toString() ;  // Outputs standard format: YYYY-MM-DD