如何使用 DateTimeFormat 为模式生成路径 yyyy/mm/dd/HH
How to generate Path with DateTimeFormat for pattern yyyy/mm/dd/HH
我正在使用 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/*
您可以使用 ChronoUnit
来获取两个日期之间的小时差。
val minutes = ChronoUnit.HOURS.between(dateTime, LocalDateTime.now())
您使用了 LocalDate
,这是一个纯日期 class,它明确不包含时间信息(这与包含时间和日期信息的 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)
更新:列出天数之间的所有时间
要列出两个日期时间之间的每个小时,您需要从 start
循环到 end
,每次使用 "plusHours"。在大多数语言中,您会为此使用 "for" 循环,但 Scala 没有 C 风格的 for 循环。在 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)
}
我正在使用 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/*
您可以使用 ChronoUnit
来获取两个日期之间的小时差。
val minutes = ChronoUnit.HOURS.between(dateTime, LocalDateTime.now())
您使用了 LocalDate
,这是一个纯日期 class,它明确不包含时间信息(这与包含时间和日期信息的 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)
更新:列出天数之间的所有时间
要列出两个日期时间之间的每个小时,您需要从 start
循环到 end
,每次使用 "plusHours"。在大多数语言中,您会为此使用 "for" 循环,但 Scala 没有 C 风格的 for 循环。在 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)
}