我正在使用spark / scala从s3加载文件。我的文件位于:
s3://bucket/yyyy/mm/dd/HH/parts...files
我需要使用startDate(string)和endDate(string)
生成文件路径import org.joda.time.{DateTime, DateTimeZone}
import org.joda.time.Days
import org.joda.time.DurationFieldType
import org.joda.time.LocalDate
import org.joda.time.format.DateTimeFormat
import org.joda.time.format.DateTimeFormatter
val startDate = "2016-09-25T04:00:00Z"
val endDate = "2016-10-23T04:00:00Z"
val s3Bucket = "s3://test_bucket/"
def getUtilDate(timestamp: String): java.sql.Date = new java.sql.Date(new DateTime(timestamp, DateTimeZone.UTC).toDate().getTime())
val start = new LocalDate(getUtilDate(startDate))
val end = new LocalDate(getUtilDate(endDate))
val days: Int = Days.daysBetween(start, end).getDays
val files: Seq[String] = (0 to days)
.map(start.plusDays)
.map(d => s"$s3Bucket${DateTimeFormat.forPattern("yyyy/MM/dd/HH").print(d)}/*")
val testFiles = sc.textFile(files.mkString(","), 20000)
val df = sqlContext.read.json(testFiles)
因为sqlContext.read.json()不采用多个路径。
但这并不能给予HH。它显示为s3://test_bucket/2016/09/26/��/*
有人可以告诉我为什么HH显示为��。有没有什么方法可以让我在两天之间获得所有时间,即在"2016-09-25T04:00:00Z" and "2016-10-23T04:00:00Z"
之间
喜欢
s3://test_bucket/2016/09/25/04/*.....
to......s3://test_bucket/2016/10/23/04/*
答案 0 :(得分:2)
您使用了LocalDate
这是一个仅限日期的类,它明确地不包含时间信息(这与包含时间和日期信息的java.sql.Date
不同)。因此,Joda无法将“HH”渲染为小时,因为它没有该信息。
尝试改为:
val startDate = "2016-09-25T04:00:00Z"
val endDate = "2016-10-23T04:00:00Z"
val s3Bucket = "s3://test_bucket/"
def getUtilDate(timestamp: String): org.joda.time.DateTime =
new DateTime(timestamp, DateTimeZone.UTC)
val start = getUtilDate(startDate)
val end = getUtilDate(endDate)
val days: Int = Days.daysBetween(start, end).getDays
val files: Seq[String] = (0 to days)
.map(start.plusDays)
.map(d => s"$s3Bucket${DateTimeFormat.forPattern("yyyy/MM/dd/HH").print(d)}/*")
println(files)
要列出两个DateTime之间的每小时,您需要从start
循环到end
,每次都使用“plusHours”。在大多数语言中,你会使用“for”循环,但Scala没有C风格的循环。在Scala中有两种主要方法可以做到这一点;我在下面展示了两个:
val startDate = "2016-09-25T04:00:00Z"
val endDate = "2016-10-23T04:00:00Z"
val s3Bucket = "s3://test_bucket/"
def getUtilDate(timestamp: String): org.joda.time.DateTime =
new DateTime(timestamp, DateTimeZone.UTC)
val start = getUtilDate(startDate)
val end = getUtilDate(endDate)
val fmt = DateTimeFormat.forPattern("yyyy/MM/dd/HH")
def bucketName(date: DateTime): String = s"$s3Bucket${fmt.print(date)}"
{
// Imperative style:
var t = start
val files = mutable.Buffer[String]()
do {
files += bucketName(t)
t = t.plusHours(1)
} while (t.compareTo(end) < 0)
println(files)
}
{
// Functional style:
@tailrec
def loop(t: DateTime, acc: Seq[String]): Seq[String] = t match {
case `end` => acc
case _ =>
loop(
t.plusHours(1),
acc :+ bucketName(t))
}
val files = loop(start, Vector())
println(files)
}
答案 1 :(得分:1)
您可以使用ChronoUnit
获取两个日期之间的HOURS差异。
val minutes = ChronoUnit.HOURS.between(dateTime, LocalDateTime.now())