Skip to content

Instantly share code, notes, and snippets.

@yangbajing
Last active December 16, 2015 04:59
Show Gist options
  • Save yangbajing/5381400 to your computer and use it in GitHub Desktop.
Save yangbajing/5381400 to your computer and use it in GitHub Desktop.
package yangbajing.util.time
object Demo extends App {
val calendar = YCalendar(LocalDate.now.minusMonths(1))
for (month <- calendar.calendarFull) {
for (week <- month) println(week.mkString(" "))
println("----------------------------------------")
}
}
package yangbajing.common
import org.joda.time.{DateTimeConstants, LocalDate, Duration, DateTime, DateTimeUtils}
import org.joda.time.format.{FormatUtils, DateTimeFormat}
object TimeHelper extends TimeHelper
trait TimeHelper {
def weeksDateTime(first: DateTime, last: DateTime): Vector[DateTime] = {
val _last = first.dayOfWeek().withMaximumValue
val duration = new Duration(first, if (last.isAfter(_last)) _last else last)
(0 to duration.toStandardDays.getDays).map(first plusDays _).toVector
}
def weeks(first: LocalDate, last: LocalDate): Vector[LocalDate] = {
val _last = first.dayOfWeek().withMaximumValue
val duration = new Duration(first.toDateTimeAtStartOfDay,
if (last.isAfter(_last)) _last.toDateTimeAtStartOfDay else last.toDateTimeAtStartOfDay)
(0 to duration.toStandardDays.getDays).map(first plusDays _).toVector
}
def monthsDateTime(first: DateTime, last: DateTime): Vector[DateTime] = {
val _last = first.dayOfMonth().withMaximumValue
val duration = new Duration(first, if (last.isAfter(_last)) _last else last)
(0 to duration.toStandardDays.getDays).map(first plusDays _).toVector
}
def months(first: LocalDate, last: LocalDate): Vector[LocalDate] = {
val _last = first.dayOfMonth().withMaximumValue
val duration = new Duration(first.toDateTimeAtStartOfDay,
if (last.isAfter(_last)) _last.toDateTimeAtStartOfDay else last.toDateTimeAtStartOfDay)
(0 to duration.toStandardDays.getDays).map(first plusDays _).toVector
}
def years(first: DateTime): Vector[Vector[DateTime]] =
(0 until 12).map {
i =>
val begin = first.plusMonths(i)
monthsDateTime(begin, begin.dayOfMonth().withMaximumValue)
}.toVector
def yearsLocalDate(first: LocalDate): Vector[Vector[LocalDate]] =
(0 until 12).map {
i =>
val begin = first.plusMonths(i)
months(begin, begin.dayOfMonth().withMaximumValue)
}.toVector
def calendarOfMonth(first: LocalDate, last: LocalDate): Vector[Vector[LocalDate]] =
_weeksOfMonth(first, last).map(v => weeks(v._1, v._2))
def calendarOfMonthDateTime(first: DateTime, last: DateTime): Vector[Vector[DateTime]] =
_weeksOfMonth(first.toLocalDate, last.toLocalDate).map(v =>
weeksDateTime(v._1.toDateTimeAtStartOfDay, v._2.toDateTimeAtStartOfDay))
private def _weeksOfMonth(first: LocalDate, _last: LocalDate): Vector[(LocalDate, LocalDate)] = {
val last = {
val tmp = first.dayOfMonth().withMaximumValue
if (_last isAfter tmp) tmp
else _last
}
@volatile
var tag = true
val tmps = collection.mutable.ArrayBuffer(first -> first.dayOfWeek().withMaximumValue())
while (tag) {
val begin = tmps.last._2.plusDays(1)
val end = begin.plusDays(6)
if (begin.isAfter(last))
tag = false
else if (end.isBefore(last))
tmps += (begin -> end)
else {
tmps += (begin -> last)
tag = false
}
}
tmps.toVector
}
val formatYear = DateTimeFormat.forPattern("yyyy")
val formatMonth = DateTimeFormat.forPattern("yyyy-MM")
val formatDate = DateTimeFormat.forPattern("yyyy-MM-dd")
val formatDateHour = DateTimeFormat.forPattern("yyyy-MM-dd HH")
val formatDateMinus = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm")
val formatDateTime = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss")
val formatDateTimeMillis = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss.SSS")
val formatMinus = DateTimeFormat.forPattern("HH:mm")
val formatTime = DateTimeFormat.forPattern("HH:mm:ss")
val formatTimeMillis = DateTimeFormat.forPattern("HH:mm:ss.SSS")
import DateTimeConstants._
def chineseWeek(d: DateTime): String = d.getDayOfWeek match {
case SUNDAY => "星期日"
case MONDAY => "星期一"
case TUESDAY => "星期二"
case WEDNESDAY => "星期三"
case THURSDAY => "星期四"
case FRIDAY => "星期五"
case SATURDAY => "星期六"
}
}
package yangbajing.common
import org.scalatest._
import org.scalatest.matchers._
import org.joda.time._
class TimeHelperSpec extends FlatSpec with ShouldMatchers with TimeHelper {
"TimeHelper" should "formater" in {
formatMonth.parseLocalDate("2013-5") should be(new LocalDate(2013, 5, 1))
formatDate.parseLocalDate("2013-05-07") should be(new LocalDate(2013, 5, 7))
formatTime.parseLocalTime("11:2:3") should be(new LocalTime(11, 2, 3))
formatMinus.parseLocalTime("11:2") should be(new LocalTime(11, 2))
formatTimeMillis.parseLocalTime("11:2:0.2") should be(new LocalTime(11, 2, 0, 200))
}
}
package yangbajing.util.time
import org.joda.time._
import yangbajing.common.TimeHelper
import java.util.{Calendar, Date}
object YCalendar {
def apply(now: DateTime): YCalendar = new YCalendar(now)
def apply(now: Date): YCalendar = apply(new DateTime(now.getTime))
def apply(now: LocalDate): YCalendar = apply(now.toDateTimeAtStartOfDay)
def apply(calendar: Calendar): YCalendar = apply(new DateTime(calendar.getTimeInMillis))
}
/**
* 此类将基于传入参数进行计算
*
* @param now
*/
class YCalendar(val now: DateTime) {
/**
* 周的所有日期
* @return
*/
def weeksDateTime: Vector[DateTime] =
TimeHelper.weeksDateTime(now.dayOfWeek().withMinimumValue, now.dayOfWeek().withMaximumValue)
def weeks: Vector[LocalDate] = {
val first = now.toLocalDate.dayOfWeek().withMinimumValue
TimeHelper.weeks(first, first.dayOfWeek().withMaximumValue)
}
/**
* 月的所有日期
* @return
*/
def monthsDateTime: Vector[DateTime] =
TimeHelper.monthsDateTime(now.dayOfMonth().withMinimumValue, now.dayOfMonth().withMaximumValue)
def months: Vector[LocalDate] = {
val first = now.toLocalDate.dayOfMonth().withMinimumValue
TimeHelper.months(first, first.dayOfMonth().withMaximumValue)
}
/**
* 日历表
*
* @return
*/
def calendar: Vector[Vector[Vector[LocalDate]]] = {
val first = now.toLocalDate.dayOfYear().withMinimumValue()
(0 until 12).map {
i =>
val begin = first.plusMonths(i)
TimeHelper.calendarOfMonth(begin, begin.dayOfMonth().withMaximumValue())
}.toVector
}
def calendarFull: Vector[Vector[Vector[LocalDate]]] =
calendar.map(calendarOfMonthFull(_))
def calendarDateTime: Vector[Vector[Vector[DateTime]]] = {
val first = now.dayOfYear().withMinimumValue()
(0 until 12).map {
i =>
val begin = first.plusMonths(i)
TimeHelper.calendarOfMonthDateTime(begin, begin.dayOfMonth().withMaximumValue())
}.toVector
}
/**
* 月份日历表
* @return
*/
def calendarOfMonth: Vector[Vector[LocalDate]] = {
val first = now.toLocalDate.dayOfMonth().withMinimumValue
TimeHelper.calendarOfMonth(first, first.dayOfMonth().withMaximumValue)
}
def calendarOfMonthFull: Vector[Vector[LocalDate]] =
calendarOfMonthFull(calendarOfMonth)
def calendarOfMonthFull(vs: Vector[Vector[LocalDate]]): Vector[Vector[LocalDate]] = {
val buffer = collection.mutable.ArrayBuffer[Vector[LocalDate]]()
vs.size match {
case 4 =>
buffer += (1 to 7).reverse.map(vs.head.head.minusDays _).toVector
buffer ++= vs
buffer += (1 to 7).reverse.map(buffer.last.last.plusDays _).toVector
case 5 =>
if (vs.head.size < 7)
buffer += ((1 to (7 - vs.head.size)).reverse.map(vs.head.head.minusDays _) ++ vs.head).toVector
else
buffer += vs.head
for (i <- 1 to 3) buffer += vs(i)
if (vs.last.size < 7)
buffer += (vs.last ++ (1 to (7 - vs.last.size)).map(vs.last.last.plusDays _)).toVector
else
buffer += vs.last
buffer += (1 to 7).map(buffer.last.last.plusDays _).toVector
case 6 =>
if (vs.head.size < 7)
buffer += ((1 to (7 - vs.head.size)).reverse.map(vs.head.head.minusDays _) ++ vs.head).toVector
else
buffer += vs.head
for (i <- 1 to 4) buffer += vs(i)
if (vs.last.size < 7)
buffer += (vs.last ++ (1 to (7 - vs.last.size)).map(vs.last.last.plusDays _)).toVector
else
buffer += vs.last
case _ =>
throw new IllegalArgumentException("月分日历表周数不正确!")
}
buffer.toVector
}
def calendarOfMonthDateTime: Vector[Vector[DateTime]] = {
val first = now.dayOfMonth().withMinimumValue
TimeHelper.calendarOfMonthDateTime(first, first.dayOfMonth().withMaximumValue)
}
/**
* 一年有所有日期
*/
def years: Vector[Vector[DateTime]] =
TimeHelper.years(now.dayOfYear().withMinimumValue)
def yearsLocalDate: Vector[Vector[LocalDate]] =
TimeHelper.yearsLocalDate(now.toLocalDate.dayOfYear().withMinimumValue)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment