Scala 如何在相同/不同年份的两周编号之间生成所有周?
在我的应用程序中,一周表示为字符串,格式为:Scala 如何在相同/不同年份的两周编号之间生成所有周?,scala,Scala,在我的应用程序中,一周表示为字符串,格式为: {year}-{week-no} // week-no ranges from 1 to 52 例如:2017年第7周表示为:2017-07 我想写一个方法,它需要两个星期的日期,并在这两个给定的星期之间生成所有的星期。因此,如果我通过: 2017-05和2017-08(相同年份):方法应返回列表(2017-052017-062017-072017-08) 2017-05和2019-02(不同年份):方法应返回列表(2017-052017-06,
{year}-{week-no} // week-no ranges from 1 to 52
例如:2017年第7周表示为:2017-07
我想写一个方法,它需要两个星期的日期,并在这两个给定的星期之间生成所有的星期。因此,如果我通过:
和2017-05
(相同年份):方法应返回2017-08
列表(2017-052017-062017-072017-08)
和2017-05
(不同年份):方法应返回2019-02
列表(2017-052017-06,……2017-512017-522018-012018-02,……2018-512018-522019-012019-02)
def weeksGenerator(fromWeek: String,toWeek: String): List[String] = {
val upperWeekNummber = fromWeek.split("-").toList.last.toInt
val upperYearNummber = fromWeek.split("-").toList.head.toInt
val lowerWeekNummber = toWeek.split("-").toList.last.toInt
val lowerYearNummber = toWeek.split("-").toList.head.toInt
(lowerYearNummber - upperYearNummber) match {
case 0L => Range.inclusive(upperWeekNummber,lowerWeekNummber).map{weekNum =>
s"${upperYearNummber.toString}-${weekNum}"
}.toList
case diff: Int =>
Range.inclusive(0,diff).foreach(println)
Range.inclusive(0,diff).flatMap{
d => if(d==diff){
// this is the last element
Range.inclusive(1,lowerWeekNummber).map{weekNum =>
s"${(upperYearNummber+d).toString}-${weekNum}"
}
}
else if(d ==0) {
// first element
Range.inclusive(upperWeekNummber,52).map{weekNum =>
s"${(upperYearNummber+d).toString}-${weekNum}"
}
}
else {
Range.inclusive(1,52).map{weekNum =>
s"${(upperYearNummber+d).toString}-${weekNum}"
}
}
}.toList
}
}
我认为我的解决方案有两个问题:
- 我不认为这是最简洁、最实用的解决方案
- 当周数从
1到9时,我想生成
,2017-01
,而不是2017-02
,2017-1
。我不想手动附加0。我正在寻找更好的方法2017-2
那么,这里最好的方法是什么呢?我可能会做以下几点:
def weeksGenerator(fromWeek: String,toWeek: String): List[String] = {
val maxWeeks = 52
val minWeeks = 1
val year1 = fromWeek.split("-")(0).toInt
val year2 = toWeek.split("-")(0).toInt
val week1 = fromWeek.split("-")(1).toInt
val week2 = toWeek.split("-")(1).toInt
val wholeWeeks = minWeeks to maxWeeks
val years = year1 to year2
val headWeeks = week1 to maxWeeks
val lastWeeks = minWeeks to week2
val enumeratedYears = years.zip(1 to years.length)
val yearsAndWeeksZip = enumeratedYears.map{case (year, index) => if (index == 1) (year, headWeeks) else if (index == years.length) (year, lastWeeks) else (year, wholeWeeks)}
val yearsAndWeeks = yearsAndWeeksZip.flatMap{case (year, weeks) => weeks.map(week => year.toString + "-" + "%02d".format(week))}
yearsAndWeeks.toList
}
您可以使用格式
正确显示数字:
scala> "%02d".format(4)
res15: String = 04
scala> "%02d".format(50)
res16: String = 50
在REPL上:
scala> weeksGenerator("2017-10", "2018-01")
res3: List[String] = List(2017-10, 2017-11, 2017-12, 2017-13, 2017-14, 2017-15, 2017-16, 2017-17, 2017-18, 2017-19, 2017-20, 2017-21, 2017-22, 2017-23, 2017-24, 2017-25, 2017-26, 2017-27, 2017-28, 2017-29, 2017-30, 2017-31, 2017-32, 2017-33, 2017-34, 2017-35, 2017-36, 2017-37, 2017-38, 2017-39, 2017-40, 2017-41, 2017-42, 2017-43, 2017-44, 2017-45, 2017-46, 2017-47, 2017-48, 2017-49, 2017-50, 2017-51, 2017-52, 2018-01)
我认为这个解决方案描述了一种使用高阶函数来解决这个问题的简洁明了的方法。它可以缩短,但我想它会失去清晰度。我可能会这样做:
def weeksGenerator(fromWeek: String,toWeek: String): List[String] = {
val maxWeeks = 52
val minWeeks = 1
val year1 = fromWeek.split("-")(0).toInt
val year2 = toWeek.split("-")(0).toInt
val week1 = fromWeek.split("-")(1).toInt
val week2 = toWeek.split("-")(1).toInt
val wholeWeeks = minWeeks to maxWeeks
val years = year1 to year2
val headWeeks = week1 to maxWeeks
val lastWeeks = minWeeks to week2
val enumeratedYears = years.zip(1 to years.length)
val yearsAndWeeksZip = enumeratedYears.map{case (year, index) => if (index == 1) (year, headWeeks) else if (index == years.length) (year, lastWeeks) else (year, wholeWeeks)}
val yearsAndWeeks = yearsAndWeeksZip.flatMap{case (year, weeks) => weeks.map(week => year.toString + "-" + "%02d".format(week))}
yearsAndWeeks.toList
}
您可以使用格式
正确显示数字:
scala> "%02d".format(4)
res15: String = 04
scala> "%02d".format(50)
res16: String = 50
在REPL上:
scala> weeksGenerator("2017-10", "2018-01")
res3: List[String] = List(2017-10, 2017-11, 2017-12, 2017-13, 2017-14, 2017-15, 2017-16, 2017-17, 2017-18, 2017-19, 2017-20, 2017-21, 2017-22, 2017-23, 2017-24, 2017-25, 2017-26, 2017-27, 2017-28, 2017-29, 2017-30, 2017-31, 2017-32, 2017-33, 2017-34, 2017-35, 2017-36, 2017-37, 2017-38, 2017-39, 2017-40, 2017-41, 2017-42, 2017-43, 2017-44, 2017-45, 2017-46, 2017-47, 2017-48, 2017-49, 2017-50, 2017-51, 2017-52, 2018-01)
我认为这个解决方案描述了一种使用高阶函数来解决这个问题的简洁明了的方法。它可以缩短,但我想它会失去清晰性。我认为最好的方法是依赖java.time api 代码可能如下所示(我不包括对输入的解析):
import java.time.DayOfWeek
导入java.time.LocalDate
导入java.time.temporal.IsoFields
导入java.time.temporal.ChronoUnit
导入java.time.format.DateTimeFormatter
导入java.time.temporal.TemporalAdjusters
val initialDate=LocalDate.ofYearDay(2017年,50)。`with`(IsoFields.WEEK\u OF the u WEEK\u OF u BASED\u YEAR,50)。`with`(temporaladjusts.previousorname(DayOfWeek.MONDAY))
val finalDate=LocalDate.ofYearDay(2017年,50)。`with`(IsoFields.WEEK,OF OF OF OF OF OF OF OF OF OF OF OF OF WEEK,OF U BASED OF U YEAR,8)。`with`(TemporalAdjusters.PreviousorName(DayOfWeek.MONDAY))
为了{
我认为最好的方法是依赖java.time api
代码可能如下所示(我不包括对输入的解析):
import java.time.DayOfWeek
导入java.time.LocalDate
导入java.time.temporal.IsoFields
导入java.time.temporal.ChronoUnit
导入java.time.format.DateTimeFormatter
导入java.time.temporal.TemporalAdjusters
val initialDate=LocalDate.ofYearDay(2017年,50)。`with`(IsoFields.WEEK\u OF the u WEEK\u OF u BASED\u YEAR,50)。`with`(temporaladjusts.previousorname(DayOfWeek.MONDAY))
val finalDate=LocalDate.ofYearDay(2017年,50)。`with`(IsoFields.WEEK,OF OF OF OF OF OF OF OF OF OF OF OF OF WEEK,OF U BASED OF U YEAR,8)。`with`(TemporalAdjusters.PreviousorName(DayOfWeek.MONDAY))
为了{
i您可以利用java time API为您完成繁重的工作(处理闰周等)。只需将您的输入解析为LocalDate
,然后使用Chrono API获取其间的周数
import java.time.LocalDate
import java.time.temporal.ChronoUnit
import java.time.format.DateTimeFormatter
def listOfWeeks(initialWeekString: String, finalWeekString: String): List[String] = {
val dateTimeFormatter = DateTimeFormatter.ofPattern("YYYY-ww-EEE")
val dateTimeFormatter2 = DateTimeFormatter.ofPattern("YYYY-ww")
val initialDate = LocalDate.parse(initialWeekString + "-Mon", dateTimeFormatter)
val finalDate = LocalDate.parse(finalWeekString + "-Mon", dateTimeFormatter)
val weeksCount = ChronoUnit.WEEKS.between(initialDate, finalDate).toInt
(0 to weeksCount)
.map(i => initialDate.plusWeeks(i).format(dateTimeFormatter2))
.toList
}
println(listOfWeeks("2017-05", "2017-06"))
// List(2017-05, 2017-06)
您可以利用java time API为您完成繁重的工作(如处理闰周等)。只需将您的输入解析为LocalDate
,然后使用Chrono API获取其间的周数
import java.time.LocalDate
import java.time.temporal.ChronoUnit
import java.time.format.DateTimeFormatter
def listOfWeeks(initialWeekString: String, finalWeekString: String): List[String] = {
val dateTimeFormatter = DateTimeFormatter.ofPattern("YYYY-ww-EEE")
val dateTimeFormatter2 = DateTimeFormatter.ofPattern("YYYY-ww")
val initialDate = LocalDate.parse(initialWeekString + "-Mon", dateTimeFormatter)
val finalDate = LocalDate.parse(finalWeekString + "-Mon", dateTimeFormatter)
val weeksCount = ChronoUnit.WEEKS.between(initialDate, finalDate).toInt
(0 to weeksCount)
.map(i => initialDate.plusWeeks(i).format(dateTimeFormatter2))
.toList
}
println(listOfWeeks("2017-05", "2017-06"))
// List(2017-05, 2017-06)
根据您的使用情况,您可能需要考虑闰周,这将使解决方案变得复杂一些。根据您的使用情况,您可能需要考虑闰周,这将使解决方案变得复杂一些。如何稍微修改解决方案,以使用适当的DateTimeFormatter更好地匹配问题要求ement?对解决方案稍加修改,以使用适当的DateTimeFormatter更好地匹配问题要求如何?很好的努力。但解决方案不起作用,因为基于周的日历和公历之间存在偏差。更准确地说,一年没有52周。很好的努力。但解决方案不起作用因为周为基础的日历和公历之间存在偏差。更确切地说,一年没有52周。