2013-07-17 21 views
10

Tôi đã dành hàng giờ cố gắng để làm cho đoạn mã tiếp theo này hoạt động.Tạo một DateRange Scala, Joda, Java

import org.joda.time.{DateTime, Period} 


def dateRange(from: DateTime, to: DateTime, step: Period): Iterator[DateTime]  =Iterator.iterate(from)(_.plus(step)).takeWhile(!_.isAfter(to)) 

val range = { 
dateRange(new DateTime(2012, 06, 30).minusYears(5), new DateTime(2000, 06, 30),new Period.months(6)) 
} 

Tôi đang cố gắng thiết lập phạm vi ngày phạm vi trải qua từ năm 2000 đến năm 2012 theo gia số 6 tháng. Vấn đề mà tôi đang phải đối mặt là lỗi sau.

Exception in thread "main" java.lang.IllegalArgumentException: No instant converter found for type: scala.Tuple3 
at org.joda.time.convert.ConverterManager.getInstantConverter(ConverterManager.java:165) 
at org.joda.time.base.BaseDateTime.<init>(BaseDateTime.java:169) 
at org.joda.time.DateTime.<init>(DateTime.java:241) 
at tester.MomentumAlgo$class.$init$(MomentumAlgo.scala:154) 
at tester.RunMomentumAlgo$$anon$1.<init>(RunMomentumAlgo.scala:86) 
at tester.RunMomentumAlgo$.main(RunMomentumAlgo.scala:86) 
at tester.RunMomentumAlgo.main(RunMomentumAlgo.scala) 
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) 
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
at java.lang.reflect.Method.invoke(Method.java:601) 
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120) 

Tôi có vẻ như liên quan đến phần Period.months() cuối cùng, tuy nhiên tôi không biết cách khắc phục. Lỗi Tuple3 mà tôi không biết.

Nếu ai đó có thể cho tôi giải pháp khác, điều đó cũng sẽ tuyệt vời. Tôi muốn có một danh sách các ngày từ năm 2000 đến năm 2012, cứ sau 6 tháng.

Mọi câu hỏi đều được chào đón. Tôi nghĩ rằng đây sẽ là một đoạn mã phổ biến, nhưng không có nhiều trên mạng về nó.

Xin cảm ơn trước.

+0

Xem này: http://www.scala-lang.org/node/6982 . Bạn có đang nhập dòng này bằng dòng trong REPL không? Tôi không thể tái tạo điều này với scala 2.10.0 và Joda Time 1.6 khi tôi biên dịch bằng 'scalac' hoặc khi tôi tải một tệp có mã trong' scala'. – Brian

+0

Xin chào Brian, tôi đã thấy chuỗi đó trước đây, mặc dù tôi không chắc chắn nên tạo ra gì, ngoài một số người khác có cùng một vấn đề. Tôi đang chạy Joda Time 1.6, nhưng Scala 2.9.2. thử thiết lập của bạn trên một hệ thống khác ngay bây giờ. Tôi đã thử scala 2.10.2 trước đó, mặc dù tôi không nghĩ rằng vấn đề nằm ở đó. – Loooit

+1

Sự cố có thể được giảm xuống đoạn mã này 'val dt = new DateTime (2013,7,16) 'như được ghi chú trong chuỗi đó, cung cấp cùng một lỗi' java.lang.IllegalArgumentException: Không có trình chuyển đổi tức thì nào được tìm thấy cho loại: scala.Tuple3 ' – Brian

Trả lời

12

Một tác phẩm xung quanh là xác định những ngày như thế này:

val date = new DateTime().withYear(2013).withMonthOfYear(7).withDayOfMonth(16) 

Toàn bộ chuỗi trong REPL sau đó trở thành này:

scala> import org.joda.time.{DateTime, Period} 
import org.joda.time.{DateTime, Period} 

scala> def dateRange(from: DateTime, to: DateTime, step: Period): Iterator[DateTime]  =Iterator.iterate(from)(_.plus(step)).takeWhile(!_.isAfter(to)) 
dateRange: (from: org.joda.time.DateTime, to: org.joda.time.DateTime, step: org.joda.time.Period)Iterator[org.joda.time.DateTime] 

scala> val from = new DateTime().withYear(2012).withMonthOfYear(6).withDayOfMonth(30).minusYears(5) 
from: org.joda.time.DateTime = 2007-06-30T21:46:05.536-07:00 

scala> val to = new DateTime().withYear(2000).withMonthOfYear(6).withDayOfMonth(30) 
to: org.joda.time.DateTime = 2000-06-30T21:46:26.186-07:00 

scala> val range = dateRange(from, to, new Period().withMonths(6)) 
range: Iterator[org.joda.time.DateTime] = non-empty iterator 

scala> range.toList 
res4: List[org.joda.time.DateTime] = List(
2000-06-30T21:46:26.186-07:00, 
2000-12-30T21:46:26.186-08:00, 
2001-06-30T21:46:26.186-07:00, 
2001-12-30T21:46:26.186-08:00, 
2002-06-30T21:46:26.186-07:00, 
2002-12-30T21:46:26.186-08:00, 
2003-06-30T21:46:26.186-07:00, 
2003-12-30T21:46:26.186-08:00, 
2004-06-30T21:46:26.186-07:00, 
2004-12-30T21:46:26.186-08:00, 
2005-06-30T21:46:26.186-07:00, 
2005-12-30T21:46:26.186-08:00, 
2006-06-30T21:46:26.186-07:00, 
2006-12-30T21:46:26.186-08:00) 

Ngoài ra, tôi đã không thể tái sản xuất này như ghi nhận trong bình luận của tôi. Dường như hành vi khác nhau trong REPL và trình biên dịch.

5

DateTimedoesn't have một constructor lấy ba int lập luận, vì vậy new DateTime(2012, 06, 30) cuộc gọi DateTime(Object) constructor với tuple (2012, 06, 30) làm đối số. Tài liệu hướng dẫn cho biết:

Xây dựng một cá thể từ một Object đại diện cho một ngày giờ.

Nếu đối tượng ngụ ý một thứ tự thời gian (chẳng hạn như GregorianCalendar), thì niên đại đó sẽ được sử dụng. Nếu không, ISO mặc định được sử dụng. Do đó, nếu một số GregorianCalendar được chuyển vào, niên đại được sử dụng sẽ là GJ, nhưng nếu một Ngày được chuyển trong niên đại sẽ là ISO.

Các loại đối tượng nhận được quy định tại ConverterManager và bao gồm ReadableInstant, String, CalendarDate. Các định dạng String được mô tả bởi ISODateTimeFormat.dateTimeParser().

Không ngạc nhiên, ConverterManager không biết phải làm gì với bộ tảo Scala, điều này dẫn đến ngoại lệ.

Nếu ai đó có thể cung cấp cho tôi giải pháp khác, điều đó cũng tuyệt vời. Tôi muốn có một danh sách các ngày từ năm 2000 đến năm 2012, cứ sau 6 tháng.

Nếu bạn thực sự muốn ngày, loại tốt hơn để sử dụng là LocalDate (trong đó có nhà xây dựng bạn muốn, nhân tiện). Nếu bạn muốn DateTime vào đầu những ngày này, thì bạn cần phải suy nghĩ về múi giờ nào sẽ được sử dụng.

4

Ok, Đây là mã hoạt động hoàn chỉnh.

import org.joda.time.{Period, DateTime} 

object runme { 

    def main(args:Array[String]) { 

    def dateRange(from: DateTime, to: DateTime, step: Period): Iterator[DateTime] 
    =Iterator.iterate(from)(_.plus(step)).takeWhile(!_.isAfter(to)) 

    val range = { dateRange(new DateTime(2000, 06, 30,0,0,0,0).minusYears(5) ,new DateTime(2013, 06, 30,0,0,0,0),new Period(0,6,0,0,0,0,0,0))} 

    range.foreach(u => { 
    print(u.getYear) 
    print(u.getMonthOfYear) 
    println(u.getDayOfMonth) 
    }) 

} 
} 

Tôi nghĩ vấn đề chính của tôi đã không có đủ số sau DateTime() chức năng (tức là mili giây, vv) này có nghĩa là trình biên dịch đã không nhận được đầy đủ các thông số mà họ muốn. Như đã đề cập bởi Alexey Romanov

Điều này sau đó in ngày cho phạm vi mong muốn và có thể được sử dụng làm trình lặp.

Hy vọng rằng sẽ giúp người khác.

Cảm ơn @ Brian và những người khác cho Trợ giúp

4

tôi cần một cái gì đó tương tự. Dưới đây là những gì tôi đã đưa ra:

import org.joda.time.{Period, DateTime} 

class DateRange(val start: DateTime, val end: DateTime, val step: Period, inclusive: Boolean) extends Iterable[DateTime] { 
    override def iterator: Iterator[DateTime] = new DateRangeIterator 

    class DateRangeIterator extends Iterator[DateTime] { 
     var current = start 

     override def hasNext: Boolean = current.isBefore(end) || (inclusive && current == end) 

     override def next(): DateTime = { 
      val returnVal = current 
      current = current.withPeriodAdded(step, 1) 
      returnVal 
     } 
    } 
} 

Ví dụ Cách sử dụng:

val startOfDay: DateTime = new DateTime().withTimeAtStartOfDay() 
val endOfDay: DateTime = startOfDay.plusDays(1) 
val dateRange = new DateRange(startOfDay, endOfDay, Period.hours(1), false) 
for (d <- dateRange) println(d) 

Output:

2015-03-16T00:00:00.000-05:00 
2015-03-16T01:00:00.000-05:00 
2015-03-16T02:00:00.000-05:00 
2015-03-16T03:00:00.000-05:00 
2015-03-16T04:00:00.000-05:00 
2015-03-16T05:00:00.000-05:00 
2015-03-16T06:00:00.000-05:00 
2015-03-16T07:00:00.000-05:00 
2015-03-16T08:00:00.000-05:00 
2015-03-16T09:00:00.000-05:00 
2015-03-16T10:00:00.000-05:00 
2015-03-16T11:00:00.000-05:00 
2015-03-16T12:00:00.000-05:00 
2015-03-16T13:00:00.000-05:00 
2015-03-16T14:00:00.000-05:00 
2015-03-16T15:00:00.000-05:00 
2015-03-16T16:00:00.000-05:00 
2015-03-16T17:00:00.000-05:00 
2015-03-16T18:00:00.000-05:00 
2015-03-16T19:00:00.000-05:00 
2015-03-16T20:00:00.000-05:00 
2015-03-16T21:00:00.000-05:00 
2015-03-16T22:00:00.000-05:00 
2015-03-16T23:00:00.000-05:00 
Các vấn đề liên quan