Skip to content

Instantly share code, notes, and snippets.

@arturopala
Last active March 14, 2023 09:33
Show Gist options
  • Save arturopala/9f76e24c5e56eb024ddf38c168dad4d1 to your computer and use it in GitHub Desktop.
Save arturopala/9f76e24c5e56eb024ddf38c168dad4d1 to your computer and use it in GitHub Desktop.
Get an official GBP-PLN currency exchange rates on the pay-dates using NBP API. Runnable using scala-cli command.
//> using scala "2.13.8"
//> using lib "com.typesafe.play::play-ahc-ws-standalone:2.1.3"
//> using lib "com.typesafe.play::play-ws-standalone-json:2.1.3"
import java.time.LocalDate
import java.time.format.DateTimeFormatter
import akka.actor.ActorSystem
import play.api.libs.ws._
import play.api.libs.ws.ahc._
import play.api.libs.json._
import play.api.libs.ws.JsonBodyReadables._
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.duration.Duration
import scala.concurrent.{Await, Future}
import com.fasterxml.jackson.core.JsonParseException
object GetRates extends App {
val year = args(0).toInt
println(s"NBP GBP-PLN exchange rates in year $year")
def getRate(currency: String, date: String): Future[BigDecimal] = {
val url =
s"http://api.nbp.pl/api/exchangerates/rates/a/$currency/$date/"
client
.url(url)
.get()
.map { response =>
(response.body[JsValue] \ "rates" \ 0 \ "mid").as[BigDecimal]
}
.recover { case e: JsonParseException =>
0
}
}
implicit val system = ActorSystem("GetRates")
val client = StandaloneAhcWSClient()
val startDate = LocalDate.of(year, 1, 1)
val firstDayOfWeek = startDate.getDayOfWeek().getValue()
val firstFriday =
if (firstDayOfWeek > 5) startDate.plusDays(12 - firstDayOfWeek)
else startDate.plusDays(5 - firstDayOfWeek)
println(
s"First Friday of the year ${firstFriday.format(DateTimeFormatter.ISO_DATE)}"
)
val endDate = LocalDate.of(year, 12, 31)
val lastFriday =
endDate.minusDays((endDate.getDayOfWeek().getValue() + 2) % 7)
println(
s"Last Friday of the year ${lastFriday.format(DateTimeFormatter.ISO_DATE)}"
)
val numberOfWeeks =
(lastFriday.getDayOfYear() - firstFriday.getDayOfYear()) / 7
println(s"Number of weeks $numberOfWeeks")
val rates = Await.result(
Future.sequence(
(0 until numberOfWeeks)
.scanLeft(firstFriday)((a, i) => a.plusDays(7))
.map(date =>
getRate("gbp", DateTimeFormatter.ISO_DATE.format(date))
.map(rate => (date, rate))
)
),
Duration.create("1m")
)
println("Found rates:")
rates.foreach { case (date, rate) =>
println(s"${date.format(DateTimeFormatter.ISO_DATE)}\t$rate")
}
System.exit(0)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment